From a7a52ef3f79f0befe70deb3fe1b1b3c01892c615 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Sun, 27 Mar 2022 17:58:28 -0700 Subject: [PATCH 01/68] Add word and line movement in vim normal mode Add jump to start and end of the document Move vim tests to relevant vim files Rename VimTestAppContext to VimTestContext for brevity Improve VimTestContext assertions to pretty print locations when selection position assertion panics --- crates/editor/src/editor.rs | 34 +-- crates/language/src/buffer.rs | 10 + crates/vim/src/editor_events.rs | 2 +- crates/vim/src/insert.rs | 19 +- crates/vim/src/mode.rs | 44 +++- crates/vim/src/normal.rs | 376 ++++++++++++++++++++++++++++- crates/vim/src/normal/g_prefix.rs | 82 +++++++ crates/vim/src/vim.rs | 45 +++- crates/vim/src/vim_test_context.rs | 179 ++++++++++++++ crates/vim/src/vim_tests.rs | 253 ------------------- 10 files changed, 766 insertions(+), 278 deletions(-) create mode 100644 crates/vim/src/normal/g_prefix.rs create mode 100644 crates/vim/src/vim_test_context.rs delete mode 100644 crates/vim/src/vim_tests.rs diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index f9327ee2519d0521fd6fb05b812411b81c9abc3a..0be43fee96c178ae9de31b154dd2a01c2dbe2055 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1281,6 +1281,24 @@ impl Editor { } } + pub fn replace_selections_with( + &mut self, + cx: &mut ViewContext, + find_replacement: impl Fn(&DisplaySnapshot) -> DisplayPoint, + ) { + let display_map = self.snapshot(cx); + let cursor = find_replacement(&display_map); + let selection = Selection { + id: post_inc(&mut self.next_selection_id), + start: cursor, + end: cursor, + reversed: false, + goal: SelectionGoal::None, + } + .map(|display_point| display_point.to_point(&display_map)); + self.update_selections(vec![selection], None, cx); + } + pub fn move_selections( &mut self, cx: &mut ViewContext, @@ -1291,21 +1309,9 @@ impl Editor { .local_selections::(cx) .into_iter() .map(|selection| { - let mut selection = Selection { - id: selection.id, - start: selection.start.to_display_point(&display_map), - end: selection.end.to_display_point(&display_map), - reversed: selection.reversed, - goal: selection.goal, - }; + let mut selection = selection.map(|point| point.to_display_point(&display_map)); move_selection(&display_map, &mut selection); - Selection { - id: selection.id, - start: selection.start.to_point(&display_map), - end: selection.end.to_point(&display_map), - reversed: selection.reversed, - goal: selection.goal, - } + selection.map(|display_point| display_point.to_point(&display_map)) }) .collect(); self.update_selections(selections, Some(Autoscroll::Fit), cx); diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 535798083eb6a5de52738e2b85a4829021a3adf9..8c200364872da5fffe18892f5684e261f2b4c5b3 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -276,6 +276,16 @@ pub enum CharKind { Word, } +impl CharKind { + pub fn coerce_punctuation(self, treat_punctuation_as_word: bool) -> Self { + if treat_punctuation_as_word && self == CharKind::Punctuation { + CharKind::Word + } else { + self + } + } +} + impl Buffer { pub fn new>>( replica_id: ReplicaId, diff --git a/crates/vim/src/editor_events.rs b/crates/vim/src/editor_events.rs index 7e49b473f9de17b5969eabfa4b8e014bf4fb7779..e4035197fd8036922cc4fa1cc5006f15948bb948 100644 --- a/crates/vim/src/editor_events.rs +++ b/crates/vim/src/editor_events.rs @@ -21,7 +21,7 @@ fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppCont let mode = if matches!(editor.read(cx).mode(), EditorMode::SingleLine) { Mode::Insert } else { - Mode::Normal + Mode::normal() }; VimState::update_global(cx, |state, cx| { diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index c027ff2c1f3de1e2d63f824e4c58df5362c6e108..9c1e36a90ef5c05c8aa4960a74572ee81a6fa34f 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -25,6 +25,23 @@ fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext CursorShape { match self { - Mode::Normal => CursorShape::Block, + Mode::Normal(_) => CursorShape::Block, Mode::Insert => CursorShape::Bar, } } @@ -20,17 +20,53 @@ impl Mode { context.map.insert( "vim_mode".to_string(), match self { - Self::Normal => "normal", + Self::Normal(_) => "normal", Self::Insert => "insert", } .to_string(), ); + + match self { + Self::Normal(normal_state) => normal_state.set_context(&mut context), + _ => {} + } context } + + pub fn normal() -> Mode { + Mode::Normal(Default::default()) + } } impl Default for Mode { fn default() -> Self { - Self::Normal + Self::Normal(Default::default()) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum NormalState { + None, + GPrefix, +} + +impl NormalState { + pub fn set_context(&self, context: &mut Context) { + let sub_mode = match self { + Self::GPrefix => Some("g"), + _ => None, + }; + + if let Some(sub_mode) = sub_mode { + context + .map + .insert("vim_sub_mode".to_string(), sub_mode.to_string()); + } + } +} + +impl Default for NormalState { + fn default() -> Self { + NormalState::None } } diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 232a76a030ae42f60ee96218a19e9b506f313392..5bf1a3c417b30fc97258dc2a44d4ee426c13af93 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -1,30 +1,55 @@ -use editor::{movement, Bias}; +mod g_prefix; + +use editor::{char_kind, movement, Bias}; use gpui::{action, keymap::Binding, MutableAppContext, ViewContext}; use language::SelectionGoal; use workspace::Workspace; -use crate::{Mode, SwitchMode, VimState}; +use crate::{mode::NormalState, Mode, SwitchMode, VimState}; -action!(InsertBefore); +action!(GPrefix); action!(MoveLeft); action!(MoveDown); action!(MoveUp); action!(MoveRight); +action!(MoveToStartOfLine); +action!(MoveToEndOfLine); +action!(MoveToEnd); +action!(MoveToNextWordStart, bool); +action!(MoveToNextWordEnd, bool); +action!(MoveToPreviousWordStart, bool); pub fn init(cx: &mut MutableAppContext) { let context = Some("Editor && vim_mode == normal"); cx.add_bindings(vec![ Binding::new("i", SwitchMode(Mode::Insert), context), + Binding::new("g", SwitchMode(Mode::Normal(NormalState::GPrefix)), context), Binding::new("h", MoveLeft, context), Binding::new("j", MoveDown, context), Binding::new("k", MoveUp, context), Binding::new("l", MoveRight, context), + Binding::new("0", MoveToStartOfLine, context), + Binding::new("shift-$", MoveToEndOfLine, context), + Binding::new("shift-G", MoveToEnd, context), + Binding::new("w", MoveToNextWordStart(false), context), + Binding::new("shift-W", MoveToNextWordStart(true), context), + Binding::new("e", MoveToNextWordEnd(false), context), + Binding::new("shift-E", MoveToNextWordEnd(true), context), + Binding::new("b", MoveToPreviousWordStart(false), context), + Binding::new("shift-B", MoveToPreviousWordStart(true), context), ]); + g_prefix::init(cx); cx.add_action(move_left); cx.add_action(move_down); cx.add_action(move_up); cx.add_action(move_right); + cx.add_action(move_to_start_of_line); + cx.add_action(move_to_end_of_line); + cx.add_action(move_to_end); + cx.add_action(move_to_next_word_start); + cx.add_action(move_to_next_word_end); + cx.add_action(move_to_previous_word_start); } fn move_left(_: &mut Workspace, _: &MoveLeft, cx: &mut ViewContext) { @@ -64,3 +89,348 @@ fn move_right(_: &mut Workspace, _: &MoveRight, cx: &mut ViewContext) }); }); } + +fn move_to_start_of_line( + _: &mut Workspace, + _: &MoveToStartOfLine, + cx: &mut ViewContext, +) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_cursors(cx, |map, cursor, _| { + ( + movement::line_beginning(map, cursor, false), + SelectionGoal::None, + ) + }); + }); + }); +} + +fn move_to_end_of_line(_: &mut Workspace, _: &MoveToEndOfLine, cx: &mut ViewContext) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_cursors(cx, |map, cursor, _| { + ( + map.clip_point(movement::line_end(map, cursor, false), Bias::Left), + SelectionGoal::None, + ) + }); + }); + }); +} + +fn move_to_end(_: &mut Workspace, _: &MoveToEnd, cx: &mut ViewContext) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.replace_selections_with(cx, |map| map.clip_point(map.max_point(), Bias::Left)); + }); + }); +} + +fn move_to_next_word_start( + _: &mut Workspace, + &MoveToNextWordStart(treat_punctuation_as_word): &MoveToNextWordStart, + cx: &mut ViewContext, +) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_cursors(cx, |map, mut cursor, _| { + let mut crossed_newline = false; + cursor = movement::find_boundary(map, cursor, |left, right| { + let left_kind = char_kind(left).coerce_punctuation(treat_punctuation_as_word); + let right_kind = char_kind(right).coerce_punctuation(treat_punctuation_as_word); + let at_newline = right == '\n'; + + let found = (left_kind != right_kind && !right.is_whitespace()) + || (at_newline && crossed_newline) + || (at_newline && left == '\n'); // Prevents skipping repeated empty lines + + if at_newline { + crossed_newline = true; + } + found + }); + (cursor, SelectionGoal::None) + }); + }); + }); +} + +fn move_to_next_word_end( + _: &mut Workspace, + &MoveToNextWordEnd(treat_punctuation_as_word): &MoveToNextWordEnd, + cx: &mut ViewContext, +) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_cursors(cx, |map, mut cursor, _| { + *cursor.column_mut() += 1; + cursor = movement::find_boundary(map, cursor, |left, right| { + let left_kind = char_kind(left).coerce_punctuation(treat_punctuation_as_word); + let right_kind = char_kind(right).coerce_punctuation(treat_punctuation_as_word); + + left_kind != right_kind && !left.is_whitespace() + }); + // find_boundary clips, so if the character after the next character is a newline or at the end of the document, we know + // we have backtraced already + if !map + .chars_at(cursor) + .skip(1) + .next() + .map(|c| c == '\n') + .unwrap_or(true) + { + *cursor.column_mut() = cursor.column().saturating_sub(1); + } + (map.clip_point(cursor, Bias::Left), SelectionGoal::None) + }); + }); + }); +} + +fn move_to_previous_word_start( + _: &mut Workspace, + &MoveToPreviousWordStart(treat_punctuation_as_word): &MoveToPreviousWordStart, + cx: &mut ViewContext, +) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_cursors(cx, |map, mut cursor, _| { + // This works even though find_preceding_boundary is called for every character in the line containing + // cursor because the newline is checked only once. + cursor = movement::find_preceding_boundary(map, cursor, |left, right| { + let left_kind = char_kind(left).coerce_punctuation(treat_punctuation_as_word); + let right_kind = char_kind(right).coerce_punctuation(treat_punctuation_as_word); + + (left_kind != right_kind && !right.is_whitespace()) || left == '\n' + }); + (cursor, SelectionGoal::None) + }); + }); + }); +} + +#[cfg(test)] +mod test { + use indoc::indoc; + use util::test::marked_text; + + use crate::vim_test_context::VimTestContext; + + #[gpui::test] + async fn test_hjkl(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true, "Test\nTestTest\nTest").await; + cx.simulate_keystroke("l"); + cx.assert_editor_state(indoc! {" + T|est + TestTest + Test"}); + cx.simulate_keystroke("h"); + cx.assert_editor_state(indoc! {" + |Test + TestTest + Test"}); + cx.simulate_keystroke("j"); + cx.assert_editor_state(indoc! {" + Test + |TestTest + Test"}); + cx.simulate_keystroke("k"); + cx.assert_editor_state(indoc! {" + |Test + TestTest + Test"}); + cx.simulate_keystroke("j"); + cx.assert_editor_state(indoc! {" + Test + |TestTest + Test"}); + + // When moving left, cursor does not wrap to the previous line + cx.simulate_keystroke("h"); + cx.assert_editor_state(indoc! {" + Test + |TestTest + Test"}); + + // When moving right, cursor does not reach the line end or wrap to the next line + for _ in 0..9 { + cx.simulate_keystroke("l"); + } + cx.assert_editor_state(indoc! {" + Test + TestTes|t + Test"}); + + // Goal column respects the inability to reach the end of the line + cx.simulate_keystroke("k"); + cx.assert_editor_state(indoc! {" + Tes|t + TestTest + Test"}); + cx.simulate_keystroke("j"); + cx.assert_editor_state(indoc! {" + Test + TestTes|t + Test"}); + } + + #[gpui::test] + async fn test_jump_to_line_boundaries(cx: &mut gpui::TestAppContext) { + let initial_content = indoc! {" + Test Test + + T"}; + let mut cx = VimTestContext::new(cx, true, initial_content).await; + + cx.simulate_keystroke("shift-$"); + cx.assert_editor_state(indoc! {" + Test Tes|t + + T"}); + cx.simulate_keystroke("0"); + cx.assert_editor_state(indoc! {" + |Test Test + + T"}); + + cx.simulate_keystroke("j"); + cx.simulate_keystroke("shift-$"); + cx.assert_editor_state(indoc! {" + Test Test + | + T"}); + cx.simulate_keystroke("0"); + cx.assert_editor_state(indoc! {" + Test Test + | + T"}); + + cx.simulate_keystroke("j"); + cx.simulate_keystroke("shift-$"); + cx.assert_editor_state(indoc! {" + Test Test + + |T"}); + cx.simulate_keystroke("0"); + cx.assert_editor_state(indoc! {" + Test Test + + |T"}); + } + + #[gpui::test] + async fn test_jump_to_end(cx: &mut gpui::TestAppContext) { + let initial_content = indoc! {" + The quick + + brown fox jumps + over the lazy dog"}; + let mut cx = VimTestContext::new(cx, true, initial_content).await; + + cx.simulate_keystroke("shift-G"); + cx.assert_editor_state(indoc! {" + The quick + + brown fox jumps + over the lazy do|g"}); + + // Repeat the action doesn't move + cx.simulate_keystroke("shift-G"); + cx.assert_editor_state(indoc! {" + The quick + + brown fox jumps + over the lazy do|g"}); + } + + #[gpui::test] + async fn test_next_word_start(cx: &mut gpui::TestAppContext) { + let (initial_content, cursor_offsets) = marked_text(indoc! {" + The |quick|-|brown + | + | + |fox_jumps |over + |th||e"}); + let mut cx = VimTestContext::new(cx, true, &initial_content).await; + + for cursor_offset in cursor_offsets { + cx.simulate_keystroke("w"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + + // Reset and test ignoring punctuation + cx.simulate_keystrokes(&["g", "g"]); + let (_, cursor_offsets) = marked_text(indoc! {" + The |quick-brown + | + | + |fox_jumps |over + |th||e"}); + + for cursor_offset in cursor_offsets { + cx.simulate_keystroke("shift-W"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + } + + #[gpui::test] + async fn test_next_word_end(cx: &mut gpui::TestAppContext) { + let (initial_content, cursor_offsets) = marked_text(indoc! {" + Th|e quic|k|-brow|n + + + fox_jump|s ove|r + th|e"}); + let mut cx = VimTestContext::new(cx, true, &initial_content).await; + + for cursor_offset in cursor_offsets { + cx.simulate_keystroke("e"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + + // Reset and test ignoring punctuation + cx.simulate_keystrokes(&["g", "g"]); + let (_, cursor_offsets) = marked_text(indoc! {" + Th|e quick-brow|n + + + fox_jump|s ove|r + th||e"}); + for cursor_offset in cursor_offsets { + cx.simulate_keystroke("shift-E"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + } + + #[gpui::test] + async fn test_previous_word_start(cx: &mut gpui::TestAppContext) { + let (initial_content, cursor_offsets) = marked_text(indoc! {" + ||The |quick|-|brown + | + | + |fox_jumps |over + |the"}); + let mut cx = VimTestContext::new(cx, true, &initial_content).await; + cx.simulate_keystroke("shift-G"); + + for cursor_offset in cursor_offsets.into_iter().rev() { + cx.simulate_keystroke("b"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + + // Reset and test ignoring punctuation + cx.simulate_keystroke("shift-G"); + let (_, cursor_offsets) = marked_text(indoc! {" + ||The |quick-brown + | + | + |fox_jumps |over + |the"}); + for cursor_offset in cursor_offsets.into_iter().rev() { + cx.simulate_keystroke("shift-B"); + cx.assert_newest_selection_head_offset(cursor_offset); + } + } +} diff --git a/crates/vim/src/normal/g_prefix.rs b/crates/vim/src/normal/g_prefix.rs new file mode 100644 index 0000000000000000000000000000000000000000..82510c0cf9364d884a465865923992e25c395586 --- /dev/null +++ b/crates/vim/src/normal/g_prefix.rs @@ -0,0 +1,82 @@ +use gpui::{action, keymap::Binding, MutableAppContext, ViewContext}; +use workspace::Workspace; + +use crate::{mode::Mode, SwitchMode, VimState}; + +action!(MoveToStart); + +pub fn init(cx: &mut MutableAppContext) { + let context = Some("Editor && vim_mode == normal && vim_sub_mode == g"); + cx.add_bindings(vec![ + Binding::new("g", MoveToStart, context), + Binding::new("escape", SwitchMode(Mode::normal()), context), + ]); + + cx.add_action(move_to_start); +} + +fn move_to_start(_: &mut Workspace, _: &MoveToStart, cx: &mut ViewContext) { + VimState::update_global(cx, |state, cx| { + state.update_active_editor(cx, |editor, cx| { + editor.move_to_beginning(&editor::MoveToBeginning, cx); + }); + state.switch_mode(&SwitchMode(Mode::normal()), cx); + }) +} + +#[cfg(test)] +mod test { + use indoc::indoc; + + use crate::{ + mode::{Mode, NormalState}, + vim_test_context::VimTestContext, + }; + + #[gpui::test] + async fn test_g_prefix_and_abort(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true, "").await; + + // Can abort with escape to get back to normal mode + cx.simulate_keystroke("g"); + assert_eq!(cx.mode(), Mode::Normal(NormalState::GPrefix)); + cx.simulate_keystroke("escape"); + assert_eq!(cx.mode(), Mode::normal()); + } + + #[gpui::test] + async fn test_move_to_start(cx: &mut gpui::TestAppContext) { + let initial_content = indoc! {" + The quick + + brown fox jumps + over the lazy dog"}; + let mut cx = VimTestContext::new(cx, true, initial_content).await; + + // Jump to the end to + cx.simulate_keystroke("shift-G"); + cx.assert_editor_state(indoc! {" + The quick + + brown fox jumps + over the lazy do|g"}); + + // Jump to the start + cx.simulate_keystrokes(&["g", "g"]); + cx.assert_editor_state(indoc! {" + |The quick + + brown fox jumps + over the lazy dog"}); + assert_eq!(cx.mode(), Mode::normal()); + + // Repeat action doesn't change + cx.simulate_keystrokes(&["g", "g"]); + cx.assert_editor_state(indoc! {" + |The quick + + brown fox jumps + over the lazy dog"}); + assert_eq!(cx.mode(), Mode::normal()); + } +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 26f7e24cf29bc7cbb919fc1c65597b7d826beb1a..609843d9696c215037cb9bef05cde9bc5c28ac14 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -3,7 +3,7 @@ mod insert; mod mode; mod normal; #[cfg(test)] -mod vim_tests; +mod vim_test_context; use collections::HashMap; use editor::{CursorShape, Editor}; @@ -65,8 +65,9 @@ impl VimState { fn set_enabled(&mut self, enabled: bool, cx: &mut MutableAppContext) { if self.enabled != enabled { self.enabled = enabled; + self.mode = Default::default(); if enabled { - self.mode = Mode::Normal; + self.mode = Mode::normal(); } self.sync_editor_options(cx); } @@ -95,3 +96,43 @@ impl VimState { } } } + +#[cfg(test)] +mod test { + use crate::{mode::Mode, vim_test_context::VimTestContext}; + + #[gpui::test] + async fn test_initially_disabled(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, false, "").await; + cx.simulate_keystrokes(&["h", "j", "k", "l"]); + cx.assert_editor_state("hjkl|"); + } + + #[gpui::test] + async fn test_toggle_through_settings(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true, "").await; + + cx.simulate_keystroke("i"); + assert_eq!(cx.mode(), Mode::Insert); + + // Editor acts as though vim is disabled + cx.disable_vim(); + cx.simulate_keystrokes(&["h", "j", "k", "l"]); + cx.assert_editor_state("hjkl|"); + + // Enabling dynamically sets vim mode again and restores normal mode + cx.enable_vim(); + assert_eq!(cx.mode(), Mode::normal()); + cx.simulate_keystrokes(&["h", "h", "h", "l"]); + assert_eq!(cx.editor_text(), "hjkl".to_owned()); + cx.assert_editor_state("hj|kl"); + cx.simulate_keystrokes(&["i", "T", "e", "s", "t"]); + cx.assert_editor_state("hjTest|kl"); + + // Disabling and enabling resets to normal mode + assert_eq!(cx.mode(), Mode::Insert); + cx.disable_vim(); + cx.enable_vim(); + assert_eq!(cx.mode(), Mode::normal()); + } +} diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs new file mode 100644 index 0000000000000000000000000000000000000000..91acc8de6ced11caded405415f97997ea4e770ff --- /dev/null +++ b/crates/vim/src/vim_test_context.rs @@ -0,0 +1,179 @@ +use std::ops::Deref; + +use editor::{display_map::ToDisplayPoint, Bias, DisplayPoint}; +use gpui::{json::json, keymap::Keystroke, ViewHandle}; +use language::{Point, Selection}; +use util::test::marked_text; +use workspace::{WorkspaceHandle, WorkspaceParams}; + +use crate::*; + +pub struct VimTestContext<'a> { + cx: &'a mut gpui::TestAppContext, + window_id: usize, + editor: ViewHandle, +} + +impl<'a> VimTestContext<'a> { + pub async fn new( + cx: &'a mut gpui::TestAppContext, + enabled: bool, + initial_editor_text: &str, + ) -> VimTestContext<'a> { + cx.update(|cx| { + editor::init(cx); + crate::init(cx); + }); + let params = cx.update(WorkspaceParams::test); + + cx.update(|cx| { + cx.update_global(|settings: &mut Settings, _| { + settings.vim_mode = enabled; + }); + }); + + params + .fs + .as_fake() + .insert_tree( + "/root", + json!({ "dir": { "test.txt": initial_editor_text } }), + ) + .await; + + let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); + params + .project + .update(cx, |project, cx| { + project.find_or_create_local_worktree("/root", true, cx) + }) + .await + .unwrap(); + cx.read(|cx| workspace.read(cx).worktree_scans_complete(cx)) + .await; + + let file = cx.read(|cx| workspace.file_project_paths(cx)[0].clone()); + let item = workspace + .update(cx, |workspace, cx| workspace.open_path(file, cx)) + .await + .expect("Could not open test file"); + + let editor = cx.update(|cx| { + item.act_as::(cx) + .expect("Opened test file wasn't an editor") + }); + editor.update(cx, |_, cx| cx.focus_self()); + + Self { + cx, + window_id, + editor, + } + } + + pub fn enable_vim(&mut self) { + self.cx.update(|cx| { + cx.update_global(|settings: &mut Settings, _| { + settings.vim_mode = true; + }); + }) + } + + pub fn disable_vim(&mut self) { + self.cx.update(|cx| { + cx.update_global(|settings: &mut Settings, _| { + settings.vim_mode = false; + }); + }) + } + + pub fn newest_selection(&mut self) -> Selection { + self.editor.update(self.cx, |editor, cx| { + let snapshot = editor.snapshot(cx); + editor + .newest_selection::(cx) + .map(|point| point.to_display_point(&snapshot.display_snapshot)) + }) + } + + pub fn mode(&mut self) -> Mode { + self.cx.update(|cx| cx.global::().mode) + } + + pub fn editor_text(&mut self) -> String { + self.editor + .update(self.cx, |editor, cx| editor.snapshot(cx).text()) + } + + pub fn simulate_keystroke(&mut self, keystroke_text: &str) { + let keystroke = Keystroke::parse(keystroke_text).unwrap(); + let input = if keystroke.modified() { + None + } else { + Some(keystroke.key.clone()) + }; + self.cx + .dispatch_keystroke(self.window_id, keystroke, input, false); + } + + pub fn simulate_keystrokes(&mut self, keystroke_texts: &[&str]) { + for keystroke_text in keystroke_texts.into_iter() { + self.simulate_keystroke(keystroke_text); + } + } + + pub fn assert_newest_selection_head_offset(&mut self, expected_offset: usize) { + let actual_head = self.newest_selection().head(); + let (actual_offset, expected_head) = self.editor.update(self.cx, |editor, cx| { + let snapshot = editor.snapshot(cx); + ( + actual_head.to_offset(&snapshot, Bias::Left), + expected_offset.to_display_point(&snapshot), + ) + }); + let mut actual_position_text = self.editor_text(); + let mut expected_position_text = actual_position_text.clone(); + actual_position_text.insert(actual_offset, '|'); + expected_position_text.insert(expected_offset, '|'); + assert_eq!( + actual_head, expected_head, + "\nActual Position: {}\nExpected Position: {}", + actual_position_text, expected_position_text + ) + } + + pub fn assert_editor_state(&mut self, text: &str) { + let (unmarked_text, markers) = marked_text(&text); + let editor_text = self.editor_text(); + assert_eq!( + editor_text, unmarked_text, + "Unmarked text doesn't match editor text" + ); + let expected_offset = markers[0]; + let actual_head = self.newest_selection().head(); + let (actual_offset, expected_head) = self.editor.update(self.cx, |editor, cx| { + let snapshot = editor.snapshot(cx); + ( + actual_head.to_offset(&snapshot, Bias::Left), + expected_offset.to_display_point(&snapshot), + ) + }); + let mut actual_position_text = self.editor_text(); + let mut expected_position_text = actual_position_text.clone(); + actual_position_text.insert(actual_offset, '|'); + expected_position_text.insert(expected_offset, '|'); + assert_eq!( + actual_head, expected_head, + "\nActual Position: {}\nExpected Position: {}", + actual_position_text, expected_position_text + ) + } +} + +impl<'a> Deref for VimTestContext<'a> { + type Target = gpui::TestAppContext; + + fn deref(&self) -> &Self::Target { + self.cx + } +} diff --git a/crates/vim/src/vim_tests.rs b/crates/vim/src/vim_tests.rs deleted file mode 100644 index 051ff21ce76575e480192024ed4b953ba1ca840e..0000000000000000000000000000000000000000 --- a/crates/vim/src/vim_tests.rs +++ /dev/null @@ -1,253 +0,0 @@ -use indoc::indoc; -use std::ops::Deref; - -use editor::{display_map::ToDisplayPoint, DisplayPoint}; -use gpui::{json::json, keymap::Keystroke, ViewHandle}; -use language::{Point, Selection}; -use util::test::marked_text; -use workspace::{WorkspaceHandle, WorkspaceParams}; - -use crate::*; - -#[gpui::test] -async fn test_insert_mode(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestAppContext::new(cx, true, "").await; - cx.simulate_keystroke("i"); - assert_eq!(cx.mode(), Mode::Insert); - cx.simulate_keystrokes(&["T", "e", "s", "t"]); - cx.assert_newest_selection_head("Test|"); - cx.simulate_keystroke("escape"); - assert_eq!(cx.mode(), Mode::Normal); - cx.assert_newest_selection_head("Tes|t"); -} - -#[gpui::test] -async fn test_normal_hjkl(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestAppContext::new(cx, true, "Test\nTestTest\nTest").await; - cx.simulate_keystroke("l"); - cx.assert_newest_selection_head(indoc! {" - T|est - TestTest - Test"}); - cx.simulate_keystroke("h"); - cx.assert_newest_selection_head(indoc! {" - |Test - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_newest_selection_head(indoc! {" - Test - |TestTest - Test"}); - cx.simulate_keystroke("k"); - cx.assert_newest_selection_head(indoc! {" - |Test - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_newest_selection_head(indoc! {" - Test - |TestTest - Test"}); - - // When moving left, cursor does not wrap to the previous line - cx.simulate_keystroke("h"); - cx.assert_newest_selection_head(indoc! {" - Test - |TestTest - Test"}); - - // When moving right, cursor does not reach the line end or wrap to the next line - for _ in 0..9 { - cx.simulate_keystroke("l"); - } - cx.assert_newest_selection_head(indoc! {" - Test - TestTes|t - Test"}); - - // Goal column respects the inability to reach the end of the line - cx.simulate_keystroke("k"); - cx.assert_newest_selection_head(indoc! {" - Tes|t - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_newest_selection_head(indoc! {" - Test - TestTes|t - Test"}); -} - -#[gpui::test] -async fn test_toggle_through_settings(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestAppContext::new(cx, true, "").await; - - cx.simulate_keystroke("i"); - assert_eq!(cx.mode(), Mode::Insert); - - // Editor acts as though vim is disabled - cx.disable_vim(); - cx.simulate_keystrokes(&["h", "j", "k", "l"]); - cx.assert_newest_selection_head("hjkl|"); - - // Enabling dynamically sets vim mode again and restores normal mode - cx.enable_vim(); - assert_eq!(cx.mode(), Mode::Normal); - cx.simulate_keystrokes(&["h", "h", "h", "l"]); - assert_eq!(cx.editor_text(), "hjkl".to_owned()); - cx.assert_newest_selection_head("hj|kl"); - cx.simulate_keystrokes(&["i", "T", "e", "s", "t"]); - cx.assert_newest_selection_head("hjTest|kl"); - - // Disabling and enabling resets to normal mode - assert_eq!(cx.mode(), Mode::Insert); - cx.disable_vim(); - assert_eq!(cx.mode(), Mode::Insert); - cx.enable_vim(); - assert_eq!(cx.mode(), Mode::Normal); -} - -#[gpui::test] -async fn test_initially_disabled(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestAppContext::new(cx, false, "").await; - cx.simulate_keystrokes(&["h", "j", "k", "l"]); - cx.assert_newest_selection_head("hjkl|"); -} - -struct VimTestAppContext<'a> { - cx: &'a mut gpui::TestAppContext, - window_id: usize, - editor: ViewHandle, -} - -impl<'a> VimTestAppContext<'a> { - async fn new( - cx: &'a mut gpui::TestAppContext, - enabled: bool, - initial_editor_text: &str, - ) -> VimTestAppContext<'a> { - cx.update(|cx| { - editor::init(cx); - crate::init(cx); - }); - let params = cx.update(WorkspaceParams::test); - - cx.update(|cx| { - cx.update_global(|settings: &mut Settings, _| { - settings.vim_mode = enabled; - }); - }); - - params - .fs - .as_fake() - .insert_tree( - "/root", - json!({ "dir": { "test.txt": initial_editor_text } }), - ) - .await; - - let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); - params - .project - .update(cx, |project, cx| { - project.find_or_create_local_worktree("/root", true, cx) - }) - .await - .unwrap(); - cx.read(|cx| workspace.read(cx).worktree_scans_complete(cx)) - .await; - - let file = cx.read(|cx| workspace.file_project_paths(cx)[0].clone()); - let item = workspace - .update(cx, |workspace, cx| workspace.open_path(file, cx)) - .await - .expect("Could not open test file"); - - let editor = cx.update(|cx| { - item.act_as::(cx) - .expect("Opened test file wasn't an editor") - }); - editor.update(cx, |_, cx| cx.focus_self()); - - Self { - cx, - window_id, - editor, - } - } - - fn enable_vim(&mut self) { - self.cx.update(|cx| { - cx.update_global(|settings: &mut Settings, _| { - settings.vim_mode = true; - }); - }) - } - - fn disable_vim(&mut self) { - self.cx.update(|cx| { - cx.update_global(|settings: &mut Settings, _| { - settings.vim_mode = false; - }); - }) - } - - fn newest_selection(&mut self) -> Selection { - self.editor.update(self.cx, |editor, cx| { - let snapshot = editor.snapshot(cx); - editor - .newest_selection::(cx) - .map(|point| point.to_display_point(&snapshot.display_snapshot)) - }) - } - - fn mode(&mut self) -> Mode { - self.cx.update(|cx| cx.global::().mode) - } - - fn editor_text(&mut self) -> String { - self.editor - .update(self.cx, |editor, cx| editor.snapshot(cx).text()) - } - - fn simulate_keystroke(&mut self, keystroke_text: &str) { - let keystroke = Keystroke::parse(keystroke_text).unwrap(); - let input = if keystroke.modified() { - None - } else { - Some(keystroke.key.clone()) - }; - self.cx - .dispatch_keystroke(self.window_id, keystroke, input, false); - } - - fn simulate_keystrokes(&mut self, keystroke_texts: &[&str]) { - for keystroke_text in keystroke_texts.into_iter() { - self.simulate_keystroke(keystroke_text); - } - } - - fn assert_newest_selection_head(&mut self, text: &str) { - let (unmarked_text, markers) = marked_text(&text); - assert_eq!( - self.editor_text(), - unmarked_text, - "Unmarked text doesn't match editor text" - ); - let newest_selection = self.newest_selection(); - let expected_head = self.editor.update(self.cx, |editor, cx| { - markers[0].to_display_point(&editor.snapshot(cx)) - }); - assert_eq!(newest_selection.head(), expected_head) - } -} - -impl<'a> Deref for VimTestAppContext<'a> { - type Target = gpui::TestAppContext; - - fn deref(&self) -> &Self::Target { - self.cx - } -} From 4d456d384706f1bf037c0383e3c15d4c307d23ef Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 28 Mar 2022 18:01:29 -0700 Subject: [PATCH 02/68] Remove duplication in build_language_registry --- crates/language/src/language.rs | 4 +- crates/zed/src/language.rs | 125 +++++++++++++++++--------------- 2 files changed, 67 insertions(+), 62 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 3fbc00c72d350c975222008cf9dc03015020ca26..bdc2e120df47a1af022202164f1f0b5c033498da 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -465,8 +465,8 @@ impl Language { Ok(self) } - pub fn with_lsp_adapter(mut self, lsp_adapter: impl LspAdapter) -> Self { - self.adapter = Some(Arc::new(lsp_adapter)); + pub fn with_lsp_adapter(mut self, lsp_adapter: Arc) -> Self { + self.adapter = Some(lsp_adapter); self } diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index 0d69ebee690a02a7dff73593c538dd978f996835..166ec2a8397f016740d16603b1811513521dfd9c 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -534,71 +534,68 @@ impl LspAdapter for JsonLspAdapter { pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegistry { let languages = LanguageRegistry::new(login_shell_env_loaded); - languages.add(Arc::new(c())); - languages.add(Arc::new(json())); - languages.add(Arc::new(rust())); - languages.add(Arc::new(markdown())); + for (name, grammar, lsp_adapter) in [ + ( + "c", + tree_sitter_c::language(), + Some(Arc::new(CLspAdapter) as Arc), + ), + ( + "json", + tree_sitter_json::language(), + Some(Arc::new(JsonLspAdapter)), + ), + ( + "markdown", + tree_sitter_markdown::language(), + None, // + ), + ( + "rust", + tree_sitter_rust::language(), + Some(Arc::new(RustLspAdapter)), + ), + ] { + languages.add(Arc::new(language(name, grammar, lsp_adapter))); + } languages } -fn rust() -> Language { - let grammar = tree_sitter_rust::language(); - let config = toml::from_slice(&LanguageDir::get("rust/config.toml").unwrap().data).unwrap(); - Language::new(config, Some(grammar)) - .with_highlights_query(load_query("rust/highlights.scm").as_ref()) - .unwrap() - .with_brackets_query(load_query("rust/brackets.scm").as_ref()) - .unwrap() - .with_indents_query(load_query("rust/indents.scm").as_ref()) - .unwrap() - .with_outline_query(load_query("rust/outline.scm").as_ref()) - .unwrap() - .with_lsp_adapter(RustLspAdapter) -} - -fn c() -> Language { - let grammar = tree_sitter_c::language(); - let config = toml::from_slice(&LanguageDir::get("c/config.toml").unwrap().data).unwrap(); - Language::new(config, Some(grammar)) - .with_highlights_query(load_query("c/highlights.scm").as_ref()) - .unwrap() - .with_brackets_query(load_query("c/brackets.scm").as_ref()) - .unwrap() - .with_indents_query(load_query("c/indents.scm").as_ref()) - .unwrap() - .with_outline_query(load_query("c/outline.scm").as_ref()) - .unwrap() - .with_lsp_adapter(CLspAdapter) -} - -fn json() -> Language { - let grammar = tree_sitter_json::language(); - let config = toml::from_slice(&LanguageDir::get("json/config.toml").unwrap().data).unwrap(); - Language::new(config, Some(grammar)) - .with_highlights_query(load_query("json/highlights.scm").as_ref()) - .unwrap() - .with_brackets_query(load_query("json/brackets.scm").as_ref()) - .unwrap() - .with_indents_query(load_query("json/indents.scm").as_ref()) - .unwrap() - .with_outline_query(load_query("json/outline.scm").as_ref()) - .unwrap() - .with_lsp_adapter(JsonLspAdapter) -} - -fn markdown() -> Language { - let grammar = tree_sitter_markdown::language(); - let config = toml::from_slice(&LanguageDir::get("markdown/config.toml").unwrap().data).unwrap(); - Language::new(config, Some(grammar)) - .with_highlights_query(load_query("markdown/highlights.scm").as_ref()) - .unwrap() +fn language( + name: &str, + grammar: tree_sitter::Language, + lsp_adapter: Option>, +) -> Language { + let config = toml::from_slice( + &LanguageDir::get(&format!("{}/config.toml", name)) + .unwrap() + .data, + ) + .unwrap(); + let mut language = Language::new(config, Some(grammar)); + if let Some(query) = load_query(&format!("{}/highlights.scm", name)) { + language = language.with_highlights_query(query.as_ref()).unwrap(); + } + if let Some(query) = load_query(&format!("{}/brackets.scm", name)) { + language = language.with_brackets_query(query.as_ref()).unwrap(); + } + if let Some(query) = load_query(&format!("{}/indents.scm", name)) { + language = language.with_indents_query(query.as_ref()).unwrap(); + } + if let Some(query) = load_query(&format!("{}/outline.scm", name)) { + language = language.with_outline_query(query.as_ref()).unwrap(); + } + if let Some(lsp_adapter) = lsp_adapter { + language = language.with_lsp_adapter(lsp_adapter) + } + language } -fn load_query(path: &str) -> Cow<'static, str> { - match LanguageDir::get(path).unwrap().data { +fn load_query(path: &str) -> Option> { + LanguageDir::get(path).map(|item| match item.data { Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), - } + }) } #[cfg(test)] @@ -651,7 +648,11 @@ mod tests { #[test] fn test_rust_label_for_completion() { - let language = rust(); + let language = language( + "rust", + tree_sitter_rust::language(), + Some(Arc::new(RustLspAdapter)), + ); let grammar = language.grammar().unwrap(); let theme = SyntaxTheme::new(vec![ ("type".into(), Color::green().into()), @@ -726,7 +727,11 @@ mod tests { #[test] fn test_rust_label_for_symbol() { - let language = rust(); + let language = language( + "rust", + tree_sitter_rust::language(), + Some(Arc::new(RustLspAdapter)), + ); let grammar = language.grammar().unwrap(); let theme = SyntaxTheme::new(vec![ ("type".into(), Color::green().into()), From a8600e76a3de34968ed27c984ed32c4f17427f46 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 28 Mar 2022 18:14:49 -0700 Subject: [PATCH 03/68] Make language's language server config non-optional --- crates/editor/src/editor.rs | 4 ++-- crates/language/src/language.rs | 24 +++++++----------------- crates/language/src/tests.rs | 1 - crates/project/src/project.rs | 24 +++++++++--------------- crates/server/src/rpc.rs | 22 +++++++++++----------- crates/zed/languages/c/config.toml | 3 --- crates/zed/languages/json/config.toml | 3 --- crates/zed/src/language.rs | 5 +++++ 8 files changed, 34 insertions(+), 52 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index f861b6ac60b1f4fe2c1b8ca83df26fed4abf9d6f..dac7adfdf823f2d18e16d0b6d1a27a4f7c321173 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8889,7 +8889,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -8979,7 +8979,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index bdc2e120df47a1af022202164f1f0b5c033498da..5b917c0fdf1e6141e7991b89d8a7f55a1455b4f6 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -51,7 +51,7 @@ lazy_static! { brackets: Default::default(), autoclose_before: Default::default(), line_comment: None, - language_server: None, + language_server: Default::default(), }, None, )); @@ -113,7 +113,8 @@ pub struct LanguageConfig { #[serde(default)] pub autoclose_before: String, pub line_comment: Option, - pub language_server: Option, + #[serde(default)] + pub language_server: LanguageServerConfig, } impl Default for LanguageConfig { @@ -251,20 +252,12 @@ impl LanguageRegistry { cx: &mut MutableAppContext, ) -> Option>> { #[cfg(any(test, feature = "test-support"))] - if language - .config - .language_server - .as_ref() - .and_then(|config| config.fake_config.as_ref()) - .is_some() - { + if language.config.language_server.fake_config.is_some() { let language = language.clone(); return Some(cx.spawn(|mut cx| async move { let fake_config = language .config .language_server - .as_ref() - .unwrap() .fake_config .as_ref() .unwrap(); @@ -478,18 +471,15 @@ impl Language { self.config.line_comment.as_deref() } - pub fn disk_based_diagnostic_sources(&self) -> Option<&HashSet> { - self.config - .language_server - .as_ref() - .map(|config| &config.disk_based_diagnostic_sources) + pub fn disk_based_diagnostic_sources(&self) -> &HashSet { + &self.config.language_server.disk_based_diagnostic_sources } pub fn disk_based_diagnostics_progress_token(&self) -> Option<&String> { self.config .language_server + .disk_based_diagnostics_progress_token .as_ref() - .and_then(|config| config.disk_based_diagnostics_progress_token.as_ref()) } pub fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams) { diff --git a/crates/language/src/tests.rs b/crates/language/src/tests.rs index 98ecf63a4692f6419707a6bc95889ddfb2cbb29f..8af4ff247ebd7f62e4c42da7345e14efff78e570 100644 --- a/crates/language/src/tests.rs +++ b/crates/language/src/tests.rs @@ -869,7 +869,6 @@ fn rust_lang() -> Language { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: None, ..Default::default() }, Some(tree_sitter_rust::language()), diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 404d867069ec383c24dac33f550ac63306468122..1a41475909d2a0a395ae5fcc7f37541e54cf25fc 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1599,14 +1599,8 @@ impl Project { ), ); } - self.update_diagnostics( - params, - language - .disk_based_diagnostic_sources() - .unwrap_or(&Default::default()), - cx, - ) - .log_err(); + self.update_diagnostics(params, language.disk_based_diagnostic_sources(), cx) + .log_err(); if disk_diagnostics_token.is_none() { self.disk_based_diagnostics_finished(cx); self.broadcast_language_server_update( @@ -4697,7 +4691,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(rust_lsp_config), + language_server: rust_lsp_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -4706,7 +4700,7 @@ mod tests { LanguageConfig { name: "JSON".into(), path_suffixes: vec!["json".to_string()], - language_server: Some(json_lsp_config), + language_server: json_lsp_config, ..Default::default() }, None, @@ -4906,7 +4900,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -5023,7 +5017,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(lsp_config), + language_server: lsp_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -5394,7 +5388,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(lsp_config), + language_server: lsp_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -5744,7 +5738,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -6680,7 +6674,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 374aaf6a7ec6820022c1802757cdabf3b51aa946..b329839de2b80912ff48299a69407ef5d8e42c4f 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -2050,7 +2050,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -2279,7 +2279,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -2474,7 +2474,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -2589,7 +2589,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -2732,7 +2732,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -2972,7 +2972,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -3119,7 +3119,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -3252,7 +3252,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -3349,7 +3349,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -3585,7 +3585,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), @@ -5456,7 +5456,7 @@ mod tests { LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: Some(language_server_config), + language_server: language_server_config, ..Default::default() }, None, diff --git a/crates/zed/languages/c/config.toml b/crates/zed/languages/c/config.toml index aeee919ac6158d9c424fb72d6c086e432dcb14f7..b7e1f0744308b202065b6052fa9994700edb5bcd 100644 --- a/crates/zed/languages/c/config.toml +++ b/crates/zed/languages/c/config.toml @@ -9,6 +9,3 @@ brackets = [ { start = "\"", end = "\"", close = true, newline = false }, { start = "/*", end = " */", close = true, newline = false }, ] - -[language_server] -disk_based_diagnostic_sources = [] \ No newline at end of file diff --git a/crates/zed/languages/json/config.toml b/crates/zed/languages/json/config.toml index 27d1193b0d75fb9eb126a5d635d1813b11b83299..ad87dcf63322f321d025a1480e77d6e9bfdb11f7 100644 --- a/crates/zed/languages/json/config.toml +++ b/crates/zed/languages/json/config.toml @@ -6,6 +6,3 @@ brackets = [ { start = "[", end = "]", close = true, newline = true }, { start = "\"", end = "\"", close = true, newline = false }, ] - -[language_server] -disk_based_diagnostic_sources = [] \ No newline at end of file diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index 166ec2a8397f016740d16603b1811513521dfd9c..fbf413c644a98cc92503b196f5184bdcb974ab7a 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -555,6 +555,11 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi tree_sitter_rust::language(), Some(Arc::new(RustLspAdapter)), ), + ( + "typescript", + tree_sitter_typescript::language_typescript(), + None, // + ), ] { languages.add(Arc::new(language(name, grammar, lsp_adapter))); } From dd1c88afa5c703ced5bb36205415d2501ce4cb23 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 28 Mar 2022 18:18:49 -0700 Subject: [PATCH 04/68] Add basic TypeScript and TSX support Co-Authored-By: Keith Simmons --- Cargo.lock | 11 + crates/zed/Cargo.toml | 1 + crates/zed/languages/tsx/brackets.scm | 1 + crates/zed/languages/tsx/config.toml | 12 + crates/zed/languages/tsx/highlights-jsx.scm | 0 crates/zed/languages/tsx/highlights.scm | 1 + crates/zed/languages/tsx/indents.scm | 1 + crates/zed/languages/tsx/outline.scm | 1 + crates/zed/languages/typescript/brackets.scm | 5 + crates/zed/languages/typescript/config.toml | 12 + .../zed/languages/typescript/highlights.scm | 219 ++++++++++++++++++ crates/zed/languages/typescript/indents.scm | 15 ++ crates/zed/languages/typescript/outline.scm | 55 +++++ crates/zed/src/language.rs | 52 +++-- 14 files changed, 373 insertions(+), 13 deletions(-) create mode 120000 crates/zed/languages/tsx/brackets.scm create mode 100644 crates/zed/languages/tsx/config.toml create mode 100644 crates/zed/languages/tsx/highlights-jsx.scm create mode 120000 crates/zed/languages/tsx/highlights.scm create mode 120000 crates/zed/languages/tsx/indents.scm create mode 120000 crates/zed/languages/tsx/outline.scm create mode 100644 crates/zed/languages/typescript/brackets.scm create mode 100644 crates/zed/languages/typescript/config.toml create mode 100644 crates/zed/languages/typescript/highlights.scm create mode 100644 crates/zed/languages/typescript/indents.scm create mode 100644 crates/zed/languages/typescript/outline.scm diff --git a/Cargo.lock b/Cargo.lock index 9c3692396461c298a0c73160fb177ee8f8c45850..a90a6d2adfe225c08ab4881bb8242ad5875bc865 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5415,6 +5415,16 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-typescript" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8ed0ecb931cdff13c6a13f45ccd615156e2779d9ffb0395864e05505e6e86d" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "ttf-parser" version = "0.9.0" @@ -6025,6 +6035,7 @@ dependencies = [ "tree-sitter-json", "tree-sitter-markdown", "tree-sitter-rust", + "tree-sitter-typescript", "unindent", "url", "util", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index fc9946b778bc8c74254b49b6fd872e402b515f36..869a6a999926bb98f176d2d03e2315238f1e9c90 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -98,6 +98,7 @@ tree-sitter-c = "0.20.1" tree-sitter-json = "0.19.0" tree-sitter-rust = "0.20.1" tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" } +tree-sitter-typescript = "0.20.1" url = "2.2" [dev-dependencies] diff --git a/crates/zed/languages/tsx/brackets.scm b/crates/zed/languages/tsx/brackets.scm new file mode 120000 index 0000000000000000000000000000000000000000..e6835c943b05c54ca6ecccc0b3bbd7673f668788 --- /dev/null +++ b/crates/zed/languages/tsx/brackets.scm @@ -0,0 +1 @@ +../typescript/brackets.scm \ No newline at end of file diff --git a/crates/zed/languages/tsx/config.toml b/crates/zed/languages/tsx/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..62717266df9e0bd56d83b336cfbf28aa2b01ee4b --- /dev/null +++ b/crates/zed/languages/tsx/config.toml @@ -0,0 +1,12 @@ +name = "TSX" +path_suffixes = ["tsx"] +line_comment = "// " +autoclose_before = ";:.,=}])>" +brackets = [ + { start = "{", end = "}", close = true, newline = true }, + { start = "[", end = "]", close = true, newline = true }, + { start = "(", end = ")", close = true, newline = true }, + { start = "<", end = ">", close = false, newline = true }, + { start = "\"", end = "\"", close = true, newline = false }, + { start = "/*", end = " */", close = true, newline = false }, +] diff --git a/crates/zed/languages/tsx/highlights-jsx.scm b/crates/zed/languages/tsx/highlights-jsx.scm new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/crates/zed/languages/tsx/highlights.scm b/crates/zed/languages/tsx/highlights.scm new file mode 120000 index 0000000000000000000000000000000000000000..226302a5d1605c7110145345be31d8e0cd96818a --- /dev/null +++ b/crates/zed/languages/tsx/highlights.scm @@ -0,0 +1 @@ +../typescript/highlights.scm \ No newline at end of file diff --git a/crates/zed/languages/tsx/indents.scm b/crates/zed/languages/tsx/indents.scm new file mode 120000 index 0000000000000000000000000000000000000000..502c2a060af208e476e793db6b0d69060f0a5377 --- /dev/null +++ b/crates/zed/languages/tsx/indents.scm @@ -0,0 +1 @@ +../typescript/indents.scm \ No newline at end of file diff --git a/crates/zed/languages/tsx/outline.scm b/crates/zed/languages/tsx/outline.scm new file mode 120000 index 0000000000000000000000000000000000000000..a0df409fda15ec9b384fc7659b5c56a6797f9034 --- /dev/null +++ b/crates/zed/languages/tsx/outline.scm @@ -0,0 +1 @@ +../typescript/outline.scm \ No newline at end of file diff --git a/crates/zed/languages/typescript/brackets.scm b/crates/zed/languages/typescript/brackets.scm new file mode 100644 index 0000000000000000000000000000000000000000..63395f81d84e6452c631a9e582e2d697cba445ef --- /dev/null +++ b/crates/zed/languages/typescript/brackets.scm @@ -0,0 +1,5 @@ +("(" @open ")" @close) +("[" @open "]" @close) +("{" @open "}" @close) +("<" @open ">" @close) +("\"" @open "\"" @close) diff --git a/crates/zed/languages/typescript/config.toml b/crates/zed/languages/typescript/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..5d491d2d329e89fe2a97ff8121c2d30c861b61d5 --- /dev/null +++ b/crates/zed/languages/typescript/config.toml @@ -0,0 +1,12 @@ +name = "TypeScript" +path_suffixes = ["ts"] +line_comment = "// " +autoclose_before = ";:.,=}])>" +brackets = [ + { start = "{", end = "}", close = true, newline = true }, + { start = "[", end = "]", close = true, newline = true }, + { start = "(", end = ")", close = true, newline = true }, + { start = "<", end = ">", close = false, newline = true }, + { start = "\"", end = "\"", close = true, newline = false }, + { start = "/*", end = " */", close = true, newline = false }, +] diff --git a/crates/zed/languages/typescript/highlights.scm b/crates/zed/languages/typescript/highlights.scm new file mode 100644 index 0000000000000000000000000000000000000000..cb4e82b33d8b04da41e90c6926499669fee33b60 --- /dev/null +++ b/crates/zed/languages/typescript/highlights.scm @@ -0,0 +1,219 @@ +; Variables + +(identifier) @variable + +; Properties + +(property_identifier) @property + +; Function and method calls + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Function and method definitions + +(function + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +(pair + key: (property_identifier) @function.method + value: [(function) (arrow_function)]) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: [(function) (arrow_function)]) + +(variable_declarator + name: (identifier) @function + value: [(function) (arrow_function)]) + +(assignment_expression + left: (identifier) @function + right: [(function) (arrow_function)]) + +; Special identifiers + +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +([ + (identifier) + (shorthand_property_identifier) + (shorthand_property_identifier_pattern) + ] @constant + (#match? @constant "^[A-Z_][A-Z\\d_]+$")) + +; Literals + +(this) @variable.builtin +(super) @variable.builtin + +[ + (true) + (false) + (null) + (undefined) +] @constant.builtin + +(comment) @comment + +[ + (string) + (template_string) +] @string + +(regex) @string.special +(number) @number + +; Tokens + +(template_substitution + "${" @punctuation.special + "}" @punctuation.special) @embedded + +[ + ";" + "?." + "." + "," +] @punctuation.delimiter + +[ + "-" + "--" + "-=" + "+" + "++" + "+=" + "*" + "*=" + "**" + "**=" + "/" + "/=" + "%" + "%=" + "<" + "<=" + "<<" + "<<=" + "=" + "==" + "===" + "!" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + ">>=" + ">>>" + ">>>=" + "~" + "^" + "&" + "|" + "^=" + "&=" + "|=" + "&&" + "||" + "??" + "&&=" + "||=" + "??=" +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "as" + "async" + "await" + "break" + "case" + "catch" + "class" + "const" + "continue" + "debugger" + "default" + "delete" + "do" + "else" + "export" + "extends" + "finally" + "for" + "from" + "function" + "get" + "if" + "import" + "in" + "instanceof" + "let" + "new" + "of" + "return" + "set" + "static" + "switch" + "target" + "throw" + "try" + "typeof" + "var" + "void" + "while" + "with" + "yield" +] @keyword + +; Types + +(type_identifier) @type +(predefined_type) @type.builtin + +((identifier) @type + (#match? @type "^[A-Z]")) + +(type_arguments + "<" @punctuation.bracket + ">" @punctuation.bracket) + +; Keywords + +[ "abstract" + "declare" + "enum" + "export" + "implements" + "interface" + "keyof" + "namespace" + "private" + "protected" + "public" + "type" + "readonly" + "override" +] @keyword \ No newline at end of file diff --git a/crates/zed/languages/typescript/indents.scm b/crates/zed/languages/typescript/indents.scm new file mode 100644 index 0000000000000000000000000000000000000000..107e6ff8e03b633f408676243c24d0d9707a2a26 --- /dev/null +++ b/crates/zed/languages/typescript/indents.scm @@ -0,0 +1,15 @@ +[ + (call_expression) + (assignment_expression) + (member_expression) + (lexical_declaration) + (variable_declaration) + (assignment_expression) + (if_statement) + (for_statement) +] @indent + +(_ "[" "]" @end) @indent +(_ "<" ">" @end) @indent +(_ "{" "}" @end) @indent +(_ "(" ")" @end) @indent diff --git a/crates/zed/languages/typescript/outline.scm b/crates/zed/languages/typescript/outline.scm new file mode 100644 index 0000000000000000000000000000000000000000..f8691fa41d9f64bc71e8a7ada2e6d64d62268a3a --- /dev/null +++ b/crates/zed/languages/typescript/outline.scm @@ -0,0 +1,55 @@ +(internal_module + "namespace" @context + name: (_) @name) @item + +(enum_declaration + "enum" @context + name: (_) @name) @item + +(function_declaration + "async"? @context + "function" @context + name: (_) @name + parameters: (formal_parameters + "(" @context + ")" @context)) @item + +(interface_declaration + "interface" @context + name: (_) @name) @item + +(program + (lexical_declaration + ["let" "const"] @context + (variable_declarator + name: (_) @name) @item)) + +(class_declaration + "class" @context + name: (_) @name) @item + +(method_definition + [ + "get" + "set" + "async" + "*" + "readonly" + "static" + (override_modifier) + (accessibility_modifier) + ]* @context + name: (_) @name + parameters: (formal_parameters + "(" @context + ")" @context)) @item + +(public_field_definition + [ + "declare" + "readonly" + "abstract" + "static" + (accessibility_modifier) + ]* @context + name: (_) @name) @item diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index fbf413c644a98cc92503b196f5184bdcb974ab7a..50540bc82cb5a6059b4fc2a02a1a3f33e3d741fc 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -555,6 +555,11 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi tree_sitter_rust::language(), Some(Arc::new(RustLspAdapter)), ), + ( + "tsx", + tree_sitter_typescript::language_tsx(), + None, // + ), ( "typescript", tree_sitter_typescript::language_typescript(), @@ -578,17 +583,26 @@ fn language( ) .unwrap(); let mut language = Language::new(config, Some(grammar)); - if let Some(query) = load_query(&format!("{}/highlights.scm", name)) { - language = language.with_highlights_query(query.as_ref()).unwrap(); + + if let Some(query) = load_query(name, "/highlights") { + language = language + .with_highlights_query(query.as_ref()) + .expect("failed to evaluate highlights query"); } - if let Some(query) = load_query(&format!("{}/brackets.scm", name)) { - language = language.with_brackets_query(query.as_ref()).unwrap(); + if let Some(query) = load_query(name, "/brackets") { + language = language + .with_brackets_query(query.as_ref()) + .expect("failed to load brackets query"); } - if let Some(query) = load_query(&format!("{}/indents.scm", name)) { - language = language.with_indents_query(query.as_ref()).unwrap(); + if let Some(query) = load_query(name, "/indents") { + language = language + .with_indents_query(query.as_ref()) + .expect("failed to load indents query"); } - if let Some(query) = load_query(&format!("{}/outline.scm", name)) { - language = language.with_outline_query(query.as_ref()).unwrap(); + if let Some(query) = load_query(name, "/outline") { + language = language + .with_outline_query(query.as_ref()) + .expect("failed to load outline query"); } if let Some(lsp_adapter) = lsp_adapter { language = language.with_lsp_adapter(lsp_adapter) @@ -596,11 +610,23 @@ fn language( language } -fn load_query(path: &str) -> Option> { - LanguageDir::get(path).map(|item| match item.data { - Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), - Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), - }) +fn load_query(name: &str, filename_prefix: &str) -> Option> { + let mut result = None; + for path in LanguageDir::iter() { + if let Some(remainder) = path.strip_prefix(name) { + if remainder.starts_with(filename_prefix) { + let contents = match LanguageDir::get(path.as_ref()).unwrap().data { + Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), + Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), + }; + match &mut result { + None => result = Some(contents), + Some(r) => r.to_mut().push_str(contents.as_ref()), + } + } + } + } + result } #[cfg(test)] From d466768eed098a2185d68b6d5b19daa57175a6fc Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 29 Mar 2022 11:06:08 -0700 Subject: [PATCH 05/68] WIP --- crates/zed/src/languages.rs | 125 ++++++ crates/zed/src/languages/c.rs | 136 +++++++ crates/zed/{ => src}/languages/c/brackets.scm | 0 crates/zed/{ => src}/languages/c/config.toml | 0 .../zed/{ => src}/languages/c/highlights.scm | 0 crates/zed/{ => src}/languages/c/indents.scm | 0 crates/zed/{ => src}/languages/c/outline.scm | 0 crates/zed/src/languages/json.rs | 131 +++++++ .../zed/{ => src}/languages/json/brackets.scm | 0 .../zed/{ => src}/languages/json/config.toml | 0 .../{ => src}/languages/json/highlights.scm | 0 .../zed/{ => src}/languages/json/indents.scm | 0 .../zed/{ => src}/languages/json/outline.scm | 0 .../{ => src}/languages/markdown/config.toml | 0 .../languages/markdown/highlights.scm | 0 .../src/{language.rs => languages/rust.rs} | 370 +----------------- .../zed/{ => src}/languages/rust/brackets.scm | 0 .../zed/{ => src}/languages/rust/config.toml | 0 .../{ => src}/languages/rust/highlights.scm | 0 .../zed/{ => src}/languages/rust/indents.scm | 0 .../zed/{ => src}/languages/rust/outline.scm | 0 .../zed/{ => src}/languages/tsx/brackets.scm | 0 .../zed/{ => src}/languages/tsx/config.toml | 0 .../languages/tsx/highlights-jsx.scm | 0 .../{ => src}/languages/tsx/highlights.scm | 0 .../zed/{ => src}/languages/tsx/indents.scm | 0 .../zed/{ => src}/languages/tsx/outline.scm | 0 crates/zed/src/languages/typescript.rs | 121 ++++++ .../languages/typescript/brackets.scm | 0 .../languages/typescript/config.toml | 0 .../languages/typescript/highlights.scm | 0 .../languages/typescript/indents.scm | 0 .../languages/typescript/outline.scm | 0 crates/zed/src/main.rs | 6 +- crates/zed/src/zed.rs | 6 +- 35 files changed, 523 insertions(+), 372 deletions(-) create mode 100644 crates/zed/src/languages.rs create mode 100644 crates/zed/src/languages/c.rs rename crates/zed/{ => src}/languages/c/brackets.scm (100%) rename crates/zed/{ => src}/languages/c/config.toml (100%) rename crates/zed/{ => src}/languages/c/highlights.scm (100%) rename crates/zed/{ => src}/languages/c/indents.scm (100%) rename crates/zed/{ => src}/languages/c/outline.scm (100%) create mode 100644 crates/zed/src/languages/json.rs rename crates/zed/{ => src}/languages/json/brackets.scm (100%) rename crates/zed/{ => src}/languages/json/config.toml (100%) rename crates/zed/{ => src}/languages/json/highlights.scm (100%) rename crates/zed/{ => src}/languages/json/indents.scm (100%) rename crates/zed/{ => src}/languages/json/outline.scm (100%) rename crates/zed/{ => src}/languages/markdown/config.toml (100%) rename crates/zed/{ => src}/languages/markdown/highlights.scm (100%) rename crates/zed/src/{language.rs => languages/rust.rs} (57%) rename crates/zed/{ => src}/languages/rust/brackets.scm (100%) rename crates/zed/{ => src}/languages/rust/config.toml (100%) rename crates/zed/{ => src}/languages/rust/highlights.scm (100%) rename crates/zed/{ => src}/languages/rust/indents.scm (100%) rename crates/zed/{ => src}/languages/rust/outline.scm (100%) rename crates/zed/{ => src}/languages/tsx/brackets.scm (100%) rename crates/zed/{ => src}/languages/tsx/config.toml (100%) rename crates/zed/{ => src}/languages/tsx/highlights-jsx.scm (100%) rename crates/zed/{ => src}/languages/tsx/highlights.scm (100%) rename crates/zed/{ => src}/languages/tsx/indents.scm (100%) rename crates/zed/{ => src}/languages/tsx/outline.scm (100%) create mode 100644 crates/zed/src/languages/typescript.rs rename crates/zed/{ => src}/languages/typescript/brackets.scm (100%) rename crates/zed/{ => src}/languages/typescript/config.toml (100%) rename crates/zed/{ => src}/languages/typescript/highlights.scm (100%) rename crates/zed/{ => src}/languages/typescript/indents.scm (100%) rename crates/zed/{ => src}/languages/typescript/outline.scm (100%) diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs new file mode 100644 index 0000000000000000000000000000000000000000..607f4c30bb756935ce315a0378ce4caf1eb16b71 --- /dev/null +++ b/crates/zed/src/languages.rs @@ -0,0 +1,125 @@ +use client::http::{self, HttpClient, Method}; +use gpui::Task; +pub use language::*; +use rust_embed::RustEmbed; +use serde::Deserialize; +use std::{borrow::Cow, str, sync::Arc}; + +mod c; +mod json; +mod rust; +mod typescript; + +#[derive(RustEmbed)] +#[folder = "src/languages"] +#[exclude = "*.rs"] +struct LanguageDir; + +#[derive(Deserialize)] +struct GithubRelease { + name: String, + assets: Vec, +} + +#[derive(Deserialize)] +struct GithubReleaseAsset { + name: String, + browser_download_url: http::Url, +} + +pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegistry { + let languages = LanguageRegistry::new(login_shell_env_loaded); + for (name, grammar, lsp_adapter) in [ + ( + "c", + tree_sitter_c::language(), + Some(Arc::new(c::CLspAdapter) as Arc), + ), + ( + "json", + tree_sitter_json::language(), + Some(Arc::new(json::JsonLspAdapter)), + ), + ( + "markdown", + tree_sitter_markdown::language(), + None, // + ), + ( + "rust", + tree_sitter_rust::language(), + Some(Arc::new(rust::RustLspAdapter)), + ), + ( + "tsx", + tree_sitter_typescript::language_tsx(), + None, // + ), + ( + "typescript", + tree_sitter_typescript::language_typescript(), + Some(Arc::new(typescript::TypeScriptLspAdapter)), + ), + ] { + languages.add(Arc::new(language(name, grammar, lsp_adapter))); + } + languages +} + +fn language( + name: &str, + grammar: tree_sitter::Language, + lsp_adapter: Option>, +) -> Language { + let config = toml::from_slice( + &LanguageDir::get(&format!("{}/config.toml", name)) + .unwrap() + .data, + ) + .unwrap(); + let mut language = Language::new(config, Some(grammar)); + + if let Some(query) = load_query(name, "/highlights") { + language = language + .with_highlights_query(query.as_ref()) + .expect("failed to evaluate highlights query"); + } + if let Some(query) = load_query(name, "/brackets") { + language = language + .with_brackets_query(query.as_ref()) + .expect("failed to load brackets query"); + } + if let Some(query) = load_query(name, "/indents") { + language = language + .with_indents_query(query.as_ref()) + .expect("failed to load indents query"); + } + if let Some(query) = load_query(name, "/outline") { + language = language + .with_outline_query(query.as_ref()) + .expect("failed to load outline query"); + } + if let Some(lsp_adapter) = lsp_adapter { + language = language.with_lsp_adapter(lsp_adapter) + } + language +} + +fn load_query(name: &str, filename_prefix: &str) -> Option> { + let mut result = None; + for path in LanguageDir::iter() { + if let Some(remainder) = path.strip_prefix(name) { + if remainder.starts_with(filename_prefix) { + let contents = match LanguageDir::get(path.as_ref()).unwrap().data { + Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), + Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), + }; + match &mut result { + None => result = Some(contents), + Some(r) => r.to_mut().push_str(contents.as_ref()), + } + } + } + } + result +} diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ce3eab2f772d86fdcc7f7a717020480660a5ed5 --- /dev/null +++ b/crates/zed/src/languages/c.rs @@ -0,0 +1,136 @@ +use anyhow::{anyhow, Result}; +use client::http::{self, HttpClient, Method}; +use futures::{future::BoxFuture, FutureExt, StreamExt}; +pub use language::*; +use smol::fs::{self, File}; +use std::{path::PathBuf, str, sync::Arc}; +use util::{ResultExt, TryFutureExt}; + +use super::GithubRelease; + +pub struct CLspAdapter; + +impl super::LspAdapter for CLspAdapter { + fn name(&self) -> &'static str { + "clangd" + } + + fn fetch_latest_server_version( + &self, + http: Arc, + ) -> BoxFuture<'static, Result> { + async move { + let release = http + .send( + surf::RequestBuilder::new( + Method::Get, + http::Url::parse( + "https://api.github.com/repos/clangd/clangd/releases/latest", + ) + .unwrap(), + ) + .middleware(surf::middleware::Redirect::default()) + .build(), + ) + .await + .map_err(|err| anyhow!("error fetching latest release: {}", err))? + .body_json::() + .await + .map_err(|err| anyhow!("error parsing latest release: {}", err))?; + let asset_name = format!("clangd-mac-{}.zip", release.name); + let asset = release + .assets + .iter() + .find(|asset| asset.name == asset_name) + .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; + Ok(LspBinaryVersion { + name: release.name, + url: Some(asset.browser_download_url.clone()), + }) + } + .boxed() + } + + fn fetch_server_binary( + &self, + version: LspBinaryVersion, + http: Arc, + container_dir: PathBuf, + ) -> BoxFuture<'static, Result> { + async move { + let zip_path = container_dir.join(format!("clangd_{}.zip", version.name)); + let version_dir = container_dir.join(format!("clangd_{}", version.name)); + let binary_path = version_dir.join("bin/clangd"); + + if fs::metadata(&binary_path).await.is_err() { + let response = http + .send( + surf::RequestBuilder::new(Method::Get, version.url.unwrap()) + .middleware(surf::middleware::Redirect::default()) + .build(), + ) + .await + .map_err(|err| anyhow!("error downloading release: {}", err))?; + let mut file = File::create(&zip_path).await?; + if !response.status().is_success() { + Err(anyhow!( + "download failed with status {}", + response.status().to_string() + ))?; + } + futures::io::copy(response, &mut file).await?; + + let unzip_status = smol::process::Command::new("unzip") + .current_dir(&container_dir) + .arg(&zip_path) + .output() + .await? + .status; + if !unzip_status.success() { + Err(anyhow!("failed to unzip clangd archive"))?; + } + + if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { + while let Some(entry) = entries.next().await { + if let Some(entry) = entry.log_err() { + let entry_path = entry.path(); + if entry_path.as_path() != version_dir { + fs::remove_dir_all(&entry_path).await.log_err(); + } + } + } + } + } + + Ok(binary_path) + } + .boxed() + } + + fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { + async move { + let mut last_clangd_dir = None; + let mut entries = fs::read_dir(&container_dir).await?; + while let Some(entry) = entries.next().await { + let entry = entry?; + if entry.file_type().await?.is_dir() { + last_clangd_dir = Some(entry.path()); + } + } + let clangd_dir = last_clangd_dir.ok_or_else(|| anyhow!("no cached binary"))?; + let clangd_bin = clangd_dir.join("bin/clangd"); + if clangd_bin.exists() { + Ok(clangd_bin) + } else { + Err(anyhow!( + "missing clangd binary in directory {:?}", + clangd_dir + )) + } + } + .log_err() + .boxed() + } + + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} +} diff --git a/crates/zed/languages/c/brackets.scm b/crates/zed/src/languages/c/brackets.scm similarity index 100% rename from crates/zed/languages/c/brackets.scm rename to crates/zed/src/languages/c/brackets.scm diff --git a/crates/zed/languages/c/config.toml b/crates/zed/src/languages/c/config.toml similarity index 100% rename from crates/zed/languages/c/config.toml rename to crates/zed/src/languages/c/config.toml diff --git a/crates/zed/languages/c/highlights.scm b/crates/zed/src/languages/c/highlights.scm similarity index 100% rename from crates/zed/languages/c/highlights.scm rename to crates/zed/src/languages/c/highlights.scm diff --git a/crates/zed/languages/c/indents.scm b/crates/zed/src/languages/c/indents.scm similarity index 100% rename from crates/zed/languages/c/indents.scm rename to crates/zed/src/languages/c/indents.scm diff --git a/crates/zed/languages/c/outline.scm b/crates/zed/src/languages/c/outline.scm similarity index 100% rename from crates/zed/languages/c/outline.scm rename to crates/zed/src/languages/c/outline.scm diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs new file mode 100644 index 0000000000000000000000000000000000000000..bb7744714f415a4db7ee1df25cb0f65027a371b7 --- /dev/null +++ b/crates/zed/src/languages/json.rs @@ -0,0 +1,131 @@ +use anyhow::{anyhow, Context, Result}; +use client::http::HttpClient; +use futures::{future::BoxFuture, FutureExt, StreamExt}; +use language::{LspAdapter, LspBinaryVersion}; +use serde::Deserialize; +use serde_json::json; +use smol::fs; +use std::{path::PathBuf, sync::Arc}; +use util::ResultExt; + +pub struct JsonLspAdapter; + +impl JsonLspAdapter { + const BIN_PATH: &'static str = + "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; +} + +impl LspAdapter for JsonLspAdapter { + fn name(&self) -> &'static str { + "vscode-json-languageserver" + } + + fn server_args(&self) -> &[&str] { + &["--stdio"] + } + + fn fetch_latest_server_version( + &self, + _: Arc, + ) -> BoxFuture<'static, Result> { + async move { + #[derive(Deserialize)] + struct NpmInfo { + versions: Vec, + } + + let output = smol::process::Command::new("npm") + .args(["info", "vscode-json-languageserver", "--json"]) + .output() + .await?; + if !output.status.success() { + Err(anyhow!("failed to execute npm info"))?; + } + let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; + + Ok(LspBinaryVersion { + name: info + .versions + .pop() + .ok_or_else(|| anyhow!("no versions found in npm info"))?, + url: Default::default(), + }) + } + .boxed() + } + + fn fetch_server_binary( + &self, + version: LspBinaryVersion, + _: Arc, + container_dir: PathBuf, + ) -> BoxFuture<'static, Result> { + async move { + let version_dir = container_dir.join(&version.name); + fs::create_dir_all(&version_dir) + .await + .context("failed to create version directory")?; + let binary_path = version_dir.join(Self::BIN_PATH); + + if fs::metadata(&binary_path).await.is_err() { + let output = smol::process::Command::new("npm") + .current_dir(&version_dir) + .arg("install") + .arg(format!("vscode-json-languageserver@{}", version.name)) + .output() + .await + .context("failed to run npm install")?; + if !output.status.success() { + Err(anyhow!("failed to install vscode-json-languageserver"))?; + } + + if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { + while let Some(entry) = entries.next().await { + if let Some(entry) = entry.log_err() { + let entry_path = entry.path(); + if entry_path.as_path() != version_dir { + fs::remove_dir_all(&entry_path).await.log_err(); + } + } + } + } + } + + Ok(binary_path) + } + .boxed() + } + + fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { + async move { + let mut last_version_dir = None; + let mut entries = fs::read_dir(&container_dir).await?; + while let Some(entry) = entries.next().await { + let entry = entry?; + if entry.file_type().await?.is_dir() { + last_version_dir = Some(entry.path()); + } + } + let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?; + let bin_path = last_version_dir.join(Self::BIN_PATH); + if bin_path.exists() { + Ok(bin_path) + } else { + Err(anyhow!( + "missing executable in directory {:?}", + last_version_dir + )) + } + } + .log_err() + .boxed() + } + + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + + fn initialization_options(&self) -> Option { + Some(json!({ + "provideFormatter": true + })) + } +} diff --git a/crates/zed/languages/json/brackets.scm b/crates/zed/src/languages/json/brackets.scm similarity index 100% rename from crates/zed/languages/json/brackets.scm rename to crates/zed/src/languages/json/brackets.scm diff --git a/crates/zed/languages/json/config.toml b/crates/zed/src/languages/json/config.toml similarity index 100% rename from crates/zed/languages/json/config.toml rename to crates/zed/src/languages/json/config.toml diff --git a/crates/zed/languages/json/highlights.scm b/crates/zed/src/languages/json/highlights.scm similarity index 100% rename from crates/zed/languages/json/highlights.scm rename to crates/zed/src/languages/json/highlights.scm diff --git a/crates/zed/languages/json/indents.scm b/crates/zed/src/languages/json/indents.scm similarity index 100% rename from crates/zed/languages/json/indents.scm rename to crates/zed/src/languages/json/indents.scm diff --git a/crates/zed/languages/json/outline.scm b/crates/zed/src/languages/json/outline.scm similarity index 100% rename from crates/zed/languages/json/outline.scm rename to crates/zed/src/languages/json/outline.scm diff --git a/crates/zed/languages/markdown/config.toml b/crates/zed/src/languages/markdown/config.toml similarity index 100% rename from crates/zed/languages/markdown/config.toml rename to crates/zed/src/languages/markdown/config.toml diff --git a/crates/zed/languages/markdown/highlights.scm b/crates/zed/src/languages/markdown/highlights.scm similarity index 100% rename from crates/zed/languages/markdown/highlights.scm rename to crates/zed/src/languages/markdown/highlights.scm diff --git a/crates/zed/src/language.rs b/crates/zed/src/languages/rust.rs similarity index 57% rename from crates/zed/src/language.rs rename to crates/zed/src/languages/rust.rs index 50540bc82cb5a6059b4fc2a02a1a3f33e3d741fc..2d4c6b3d3673c1117abbe86fcfc48044f283cf05 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/languages/rust.rs @@ -1,37 +1,17 @@ -use anyhow::{anyhow, Context, Result}; +use anyhow::{anyhow, Result}; use async_compression::futures::bufread::GzipDecoder; use client::http::{self, HttpClient, Method}; use futures::{future::BoxFuture, FutureExt, StreamExt}; -use gpui::Task; pub use language::*; use lazy_static::lazy_static; use regex::Regex; -use rust_embed::RustEmbed; -use serde::Deserialize; -use serde_json::json; use smol::fs::{self, File}; use std::{borrow::Cow, env::consts, path::PathBuf, str, sync::Arc}; use util::{ResultExt, TryFutureExt}; -#[derive(RustEmbed)] -#[folder = "languages"] -struct LanguageDir; +use super::GithubRelease; -struct RustLspAdapter; -struct CLspAdapter; -struct JsonLspAdapter; - -#[derive(Deserialize)] -struct GithubRelease { - name: String, - assets: Vec, -} - -#[derive(Deserialize)] -struct GithubReleaseAsset { - name: String, - browser_download_url: http::Url, -} +pub struct RustLspAdapter; impl LspAdapter for RustLspAdapter { fn name(&self) -> &'static str { @@ -287,353 +267,11 @@ impl LspAdapter for RustLspAdapter { } } -impl LspAdapter for CLspAdapter { - fn name(&self) -> &'static str { - "clangd" - } - - fn fetch_latest_server_version( - &self, - http: Arc, - ) -> BoxFuture<'static, Result> { - async move { - let release = http - .send( - surf::RequestBuilder::new( - Method::Get, - http::Url::parse( - "https://api.github.com/repos/clangd/clangd/releases/latest", - ) - .unwrap(), - ) - .middleware(surf::middleware::Redirect::default()) - .build(), - ) - .await - .map_err(|err| anyhow!("error fetching latest release: {}", err))? - .body_json::() - .await - .map_err(|err| anyhow!("error parsing latest release: {}", err))?; - let asset_name = format!("clangd-mac-{}.zip", release.name); - let asset = release - .assets - .iter() - .find(|asset| asset.name == asset_name) - .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; - Ok(LspBinaryVersion { - name: release.name, - url: Some(asset.browser_download_url.clone()), - }) - } - .boxed() - } - - fn fetch_server_binary( - &self, - version: LspBinaryVersion, - http: Arc, - container_dir: PathBuf, - ) -> BoxFuture<'static, Result> { - async move { - let zip_path = container_dir.join(format!("clangd_{}.zip", version.name)); - let version_dir = container_dir.join(format!("clangd_{}", version.name)); - let binary_path = version_dir.join("bin/clangd"); - - if fs::metadata(&binary_path).await.is_err() { - let response = http - .send( - surf::RequestBuilder::new(Method::Get, version.url.unwrap()) - .middleware(surf::middleware::Redirect::default()) - .build(), - ) - .await - .map_err(|err| anyhow!("error downloading release: {}", err))?; - let mut file = File::create(&zip_path).await?; - if !response.status().is_success() { - Err(anyhow!( - "download failed with status {}", - response.status().to_string() - ))?; - } - futures::io::copy(response, &mut file).await?; - - let unzip_status = smol::process::Command::new("unzip") - .current_dir(&container_dir) - .arg(&zip_path) - .output() - .await? - .status; - if !unzip_status.success() { - Err(anyhow!("failed to unzip clangd archive"))?; - } - - if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { - while let Some(entry) = entries.next().await { - if let Some(entry) = entry.log_err() { - let entry_path = entry.path(); - if entry_path.as_path() != version_dir { - fs::remove_dir_all(&entry_path).await.log_err(); - } - } - } - } - } - - Ok(binary_path) - } - .boxed() - } - - fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { - async move { - let mut last_clangd_dir = None; - let mut entries = fs::read_dir(&container_dir).await?; - while let Some(entry) = entries.next().await { - let entry = entry?; - if entry.file_type().await?.is_dir() { - last_clangd_dir = Some(entry.path()); - } - } - let clangd_dir = last_clangd_dir.ok_or_else(|| anyhow!("no cached binary"))?; - let clangd_bin = clangd_dir.join("bin/clangd"); - if clangd_bin.exists() { - Ok(clangd_bin) - } else { - Err(anyhow!( - "missing clangd binary in directory {:?}", - clangd_dir - )) - } - } - .log_err() - .boxed() - } - - fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} -} - -impl JsonLspAdapter { - const BIN_PATH: &'static str = - "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; -} - -impl LspAdapter for JsonLspAdapter { - fn name(&self) -> &'static str { - "vscode-json-languageserver" - } - - fn server_args(&self) -> &[&str] { - &["--stdio"] - } - - fn fetch_latest_server_version( - &self, - _: Arc, - ) -> BoxFuture<'static, Result> { - async move { - #[derive(Deserialize)] - struct NpmInfo { - versions: Vec, - } - - let output = smol::process::Command::new("npm") - .args(["info", "vscode-json-languageserver", "--json"]) - .output() - .await?; - if !output.status.success() { - Err(anyhow!("failed to execute npm info"))?; - } - let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; - - Ok(LspBinaryVersion { - name: info - .versions - .pop() - .ok_or_else(|| anyhow!("no versions found in npm info"))?, - url: Default::default(), - }) - } - .boxed() - } - - fn fetch_server_binary( - &self, - version: LspBinaryVersion, - _: Arc, - container_dir: PathBuf, - ) -> BoxFuture<'static, Result> { - async move { - let version_dir = container_dir.join(&version.name); - fs::create_dir_all(&version_dir) - .await - .context("failed to create version directory")?; - let binary_path = version_dir.join(Self::BIN_PATH); - - if fs::metadata(&binary_path).await.is_err() { - let output = smol::process::Command::new("npm") - .current_dir(&version_dir) - .arg("install") - .arg(format!("vscode-json-languageserver@{}", version.name)) - .output() - .await - .context("failed to run npm install")?; - if !output.status.success() { - Err(anyhow!("failed to install vscode-json-languageserver"))?; - } - - if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { - while let Some(entry) = entries.next().await { - if let Some(entry) = entry.log_err() { - let entry_path = entry.path(); - if entry_path.as_path() != version_dir { - fs::remove_dir_all(&entry_path).await.log_err(); - } - } - } - } - } - - Ok(binary_path) - } - .boxed() - } - - fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { - async move { - let mut last_version_dir = None; - let mut entries = fs::read_dir(&container_dir).await?; - while let Some(entry) = entries.next().await { - let entry = entry?; - if entry.file_type().await?.is_dir() { - last_version_dir = Some(entry.path()); - } - } - let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?; - let bin_path = last_version_dir.join(Self::BIN_PATH); - if bin_path.exists() { - Ok(bin_path) - } else { - Err(anyhow!( - "missing executable in directory {:?}", - last_version_dir - )) - } - } - .log_err() - .boxed() - } - - fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} - - fn initialization_options(&self) -> Option { - Some(json!({ - "provideFormatter": true - })) - } -} - -pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegistry { - let languages = LanguageRegistry::new(login_shell_env_loaded); - for (name, grammar, lsp_adapter) in [ - ( - "c", - tree_sitter_c::language(), - Some(Arc::new(CLspAdapter) as Arc), - ), - ( - "json", - tree_sitter_json::language(), - Some(Arc::new(JsonLspAdapter)), - ), - ( - "markdown", - tree_sitter_markdown::language(), - None, // - ), - ( - "rust", - tree_sitter_rust::language(), - Some(Arc::new(RustLspAdapter)), - ), - ( - "tsx", - tree_sitter_typescript::language_tsx(), - None, // - ), - ( - "typescript", - tree_sitter_typescript::language_typescript(), - None, // - ), - ] { - languages.add(Arc::new(language(name, grammar, lsp_adapter))); - } - languages -} - -fn language( - name: &str, - grammar: tree_sitter::Language, - lsp_adapter: Option>, -) -> Language { - let config = toml::from_slice( - &LanguageDir::get(&format!("{}/config.toml", name)) - .unwrap() - .data, - ) - .unwrap(); - let mut language = Language::new(config, Some(grammar)); - - if let Some(query) = load_query(name, "/highlights") { - language = language - .with_highlights_query(query.as_ref()) - .expect("failed to evaluate highlights query"); - } - if let Some(query) = load_query(name, "/brackets") { - language = language - .with_brackets_query(query.as_ref()) - .expect("failed to load brackets query"); - } - if let Some(query) = load_query(name, "/indents") { - language = language - .with_indents_query(query.as_ref()) - .expect("failed to load indents query"); - } - if let Some(query) = load_query(name, "/outline") { - language = language - .with_outline_query(query.as_ref()) - .expect("failed to load outline query"); - } - if let Some(lsp_adapter) = lsp_adapter { - language = language.with_lsp_adapter(lsp_adapter) - } - language -} - -fn load_query(name: &str, filename_prefix: &str) -> Option> { - let mut result = None; - for path in LanguageDir::iter() { - if let Some(remainder) = path.strip_prefix(name) { - if remainder.starts_with(filename_prefix) { - let contents = match LanguageDir::get(path.as_ref()).unwrap().data { - Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), - Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), - }; - match &mut result { - None => result = Some(contents), - Some(r) => r.to_mut().push_str(contents.as_ref()), - } - } - } - } - result -} - #[cfg(test)] mod tests { use super::*; + use crate::languages::{language, LspAdapter}; use gpui::color::Color; - use language::LspAdapter; use theme::SyntaxTheme; #[test] diff --git a/crates/zed/languages/rust/brackets.scm b/crates/zed/src/languages/rust/brackets.scm similarity index 100% rename from crates/zed/languages/rust/brackets.scm rename to crates/zed/src/languages/rust/brackets.scm diff --git a/crates/zed/languages/rust/config.toml b/crates/zed/src/languages/rust/config.toml similarity index 100% rename from crates/zed/languages/rust/config.toml rename to crates/zed/src/languages/rust/config.toml diff --git a/crates/zed/languages/rust/highlights.scm b/crates/zed/src/languages/rust/highlights.scm similarity index 100% rename from crates/zed/languages/rust/highlights.scm rename to crates/zed/src/languages/rust/highlights.scm diff --git a/crates/zed/languages/rust/indents.scm b/crates/zed/src/languages/rust/indents.scm similarity index 100% rename from crates/zed/languages/rust/indents.scm rename to crates/zed/src/languages/rust/indents.scm diff --git a/crates/zed/languages/rust/outline.scm b/crates/zed/src/languages/rust/outline.scm similarity index 100% rename from crates/zed/languages/rust/outline.scm rename to crates/zed/src/languages/rust/outline.scm diff --git a/crates/zed/languages/tsx/brackets.scm b/crates/zed/src/languages/tsx/brackets.scm similarity index 100% rename from crates/zed/languages/tsx/brackets.scm rename to crates/zed/src/languages/tsx/brackets.scm diff --git a/crates/zed/languages/tsx/config.toml b/crates/zed/src/languages/tsx/config.toml similarity index 100% rename from crates/zed/languages/tsx/config.toml rename to crates/zed/src/languages/tsx/config.toml diff --git a/crates/zed/languages/tsx/highlights-jsx.scm b/crates/zed/src/languages/tsx/highlights-jsx.scm similarity index 100% rename from crates/zed/languages/tsx/highlights-jsx.scm rename to crates/zed/src/languages/tsx/highlights-jsx.scm diff --git a/crates/zed/languages/tsx/highlights.scm b/crates/zed/src/languages/tsx/highlights.scm similarity index 100% rename from crates/zed/languages/tsx/highlights.scm rename to crates/zed/src/languages/tsx/highlights.scm diff --git a/crates/zed/languages/tsx/indents.scm b/crates/zed/src/languages/tsx/indents.scm similarity index 100% rename from crates/zed/languages/tsx/indents.scm rename to crates/zed/src/languages/tsx/indents.scm diff --git a/crates/zed/languages/tsx/outline.scm b/crates/zed/src/languages/tsx/outline.scm similarity index 100% rename from crates/zed/languages/tsx/outline.scm rename to crates/zed/src/languages/tsx/outline.scm diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs new file mode 100644 index 0000000000000000000000000000000000000000..59b7d225f9cb4dc1850e3a42280011dd37d7454d --- /dev/null +++ b/crates/zed/src/languages/typescript.rs @@ -0,0 +1,121 @@ +pub struct TypeScriptLspAdapter; + +impl TypeScriptLspAdapter { + const BIN_PATH: &'static str = + "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; +} + +impl super::LspAdapter for TypeScriptLspAdapter { + fn name(&self) -> &'static str { + "typescript-language-server" + } + + fn server_args(&self) -> &[&str] { + &["--stdio"] + } + + fn fetch_latest_server_version( + &self, + _: Arc, + ) -> BoxFuture<'static, Result> { + async move { + #[derive(Deserialize)] + struct NpmInfo { + versions: Vec, + } + + let output = smol::process::Command::new("npm") + .args(["info", "vscode-json-languageserver", "--json"]) + .output() + .await?; + if !output.status.success() { + Err(anyhow!("failed to execute npm info"))?; + } + let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; + + Ok(LspBinaryVersion { + name: info + .versions + .pop() + .ok_or_else(|| anyhow!("no versions found in npm info"))?, + url: Default::default(), + }) + } + .boxed() + } + + fn fetch_server_binary( + &self, + version: LspBinaryVersion, + _: Arc, + container_dir: PathBuf, + ) -> BoxFuture<'static, Result> { + async move { + let version_dir = container_dir.join(&version.name); + fs::create_dir_all(&version_dir) + .await + .context("failed to create version directory")?; + let binary_path = version_dir.join(Self::BIN_PATH); + + if fs::metadata(&binary_path).await.is_err() { + let output = smol::process::Command::new("npm") + .current_dir(&version_dir) + .arg("install") + .arg(format!("vscode-json-languageserver@{}", version.name)) + .output() + .await + .context("failed to run npm install")?; + if !output.status.success() { + Err(anyhow!("failed to install vscode-json-languageserver"))?; + } + + if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { + while let Some(entry) = entries.next().await { + if let Some(entry) = entry.log_err() { + let entry_path = entry.path(); + if entry_path.as_path() != version_dir { + fs::remove_dir_all(&entry_path).await.log_err(); + } + } + } + } + } + + Ok(binary_path) + } + .boxed() + } + + fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { + async move { + let mut last_version_dir = None; + let mut entries = fs::read_dir(&container_dir).await?; + while let Some(entry) = entries.next().await { + let entry = entry?; + if entry.file_type().await?.is_dir() { + last_version_dir = Some(entry.path()); + } + } + let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?; + let bin_path = last_version_dir.join(Self::BIN_PATH); + if bin_path.exists() { + Ok(bin_path) + } else { + Err(anyhow!( + "missing executable in directory {:?}", + last_version_dir + )) + } + } + .log_err() + .boxed() + } + + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + + fn initialization_options(&self) -> Option { + Some(json!({ + "provideFormatter": true + })) + } +} diff --git a/crates/zed/languages/typescript/brackets.scm b/crates/zed/src/languages/typescript/brackets.scm similarity index 100% rename from crates/zed/languages/typescript/brackets.scm rename to crates/zed/src/languages/typescript/brackets.scm diff --git a/crates/zed/languages/typescript/config.toml b/crates/zed/src/languages/typescript/config.toml similarity index 100% rename from crates/zed/languages/typescript/config.toml rename to crates/zed/src/languages/typescript/config.toml diff --git a/crates/zed/languages/typescript/highlights.scm b/crates/zed/src/languages/typescript/highlights.scm similarity index 100% rename from crates/zed/languages/typescript/highlights.scm rename to crates/zed/src/languages/typescript/highlights.scm diff --git a/crates/zed/languages/typescript/indents.scm b/crates/zed/src/languages/typescript/indents.scm similarity index 100% rename from crates/zed/languages/typescript/indents.scm rename to crates/zed/src/languages/typescript/indents.scm diff --git a/crates/zed/languages/typescript/outline.scm b/crates/zed/src/languages/typescript/outline.scm similarity index 100% rename from crates/zed/languages/typescript/outline.scm rename to crates/zed/src/languages/typescript/outline.scm diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 63721346c399ca60ea4f701f330ad78fb61d63e0..49efc9ade2af2749cca42cc20362a1c174dea833 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -19,7 +19,7 @@ use workspace::{ AppState, OpenNew, OpenParams, OpenPaths, Settings, }; use zed::{ - self, assets::Assets, build_window_options, build_workspace, fs::RealFs, language, menus, + self, assets::Assets, build_window_options, build_workspace, fs::RealFs, languages, menus, }; fn main() { @@ -34,7 +34,7 @@ fn main() { let default_settings = Settings::new("Zed Mono", &app.font_cache(), theme) .unwrap() .with_overrides( - language::PLAIN_TEXT.name(), + languages::PLAIN_TEXT.name(), settings::LanguageOverride { soft_wrap: Some(settings::SoftWrap::PreferredLineLength), ..Default::default() @@ -60,7 +60,7 @@ fn main() { app.run(move |cx| { let http = http::client(); let client = client::Client::new(http.clone()); - let mut languages = language::build_language_registry(login_shell_env_loaded); + let mut languages = languages::build_language_registry(login_shell_env_loaded); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx)); let channel_list = cx.add_model(|cx| ChannelList::new(user_store.clone(), client.clone(), cx)); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 1302d54067810653140367b40966e869edcf8372..25aa011c9b5ec801a79f8e7a5720904e862a6b4a 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1,5 +1,5 @@ pub mod assets; -pub mod language; +pub mod languages; pub mod menus; #[cfg(any(test, feature = "test-support"))] pub mod test; @@ -557,7 +557,7 @@ mod tests { assert_eq!(editor.title(cx), "untitled"); assert!(Arc::ptr_eq( editor.language(cx).unwrap(), - &language::PLAIN_TEXT + &languages::PLAIN_TEXT )); editor.handle_input(&editor::Input("hi".into()), cx); assert!(editor.is_dirty(cx)); @@ -647,7 +647,7 @@ mod tests { editor.update(cx, |editor, cx| { assert!(Arc::ptr_eq( editor.language(cx).unwrap(), - &language::PLAIN_TEXT + &languages::PLAIN_TEXT )); editor.handle_input(&editor::Input("hi".into()), cx); assert!(editor.is_dirty(cx.as_ref())); From 0e1d371a67b1483e4ab7a426b12938cb5b0abdde Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Tue, 29 Mar 2022 13:42:21 -0700 Subject: [PATCH 06/68] Add typescript language server Currently not tested for tsx files Co-authored-by: Max Brunsfeld --- crates/language/src/language.rs | 9 ++-- crates/project/src/project.rs | 8 +-- crates/zed/src/languages.rs | 4 +- crates/zed/src/languages/c.rs | 15 +++--- crates/zed/src/languages/json.rs | 23 ++++----- crates/zed/src/languages/rust.rs | 15 +++--- crates/zed/src/languages/typescript.rs | 69 +++++++++++++++++++------- 7 files changed, 90 insertions(+), 53 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 5b917c0fdf1e6141e7991b89d8a7f55a1455b4f6..6e400c4a6fa2e5a5f35ee84ee9339cba190a2741 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -20,6 +20,7 @@ use parking_lot::{Mutex, RwLock}; use serde::Deserialize; use serde_json::Value; use std::{ + any::Any, cell::RefCell, ops::Range, path::{Path, PathBuf}, @@ -61,9 +62,9 @@ pub trait ToLspPosition { fn to_lsp_position(self) -> lsp::Position; } -pub struct LspBinaryVersion { +pub struct GitHubLspBinaryVersion { pub name: String, - pub url: Option, + pub url: http::Url, } pub trait LspAdapter: 'static + Send + Sync { @@ -71,10 +72,10 @@ pub trait LspAdapter: 'static + Send + Sync { fn fetch_latest_server_version( &self, http: Arc, - ) -> BoxFuture<'static, Result>; + ) -> BoxFuture<'static, Result>>; fn fetch_server_binary( &self, - version: LspBinaryVersion, + version: Box, http: Arc, container_dir: PathBuf, ) -> BoxFuture<'static, Result>; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 1a41475909d2a0a395ae5fcc7f37541e54cf25fc..f4d5e9ee11e855cbfe43e8a05dd6ad9a06027faf 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2278,11 +2278,12 @@ impl Project { Ok(completions .into_iter() .filter_map(|lsp_completion| { - let (old_range, new_text) = match lsp_completion.text_edit.as_ref()? { - lsp::CompletionTextEdit::Edit(edit) => { + let (old_range, new_text) = match lsp_completion.text_edit.as_ref() { + Some(lsp::CompletionTextEdit::Edit(edit)) => { (range_from_lsp(edit.range), edit.new_text.clone()) } - lsp::CompletionTextEdit::InsertAndReplace(_) => { + None => (position..position, lsp_completion.label.clone()), + Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { log::info!("unsupported insert/replace completion"); return None; } @@ -2307,6 +2308,7 @@ impl Project { lsp_completion, }) } else { + log::info!("completion out of expected range"); None } }) diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index 607f4c30bb756935ce315a0378ce4caf1eb16b71..cc22247025a393cb104ee4317bc76a47155988d3 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -1,4 +1,4 @@ -use client::http::{self, HttpClient, Method}; +use client::http; use gpui::Task; pub use language::*; use rust_embed::RustEmbed; @@ -53,7 +53,7 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi ( "tsx", tree_sitter_typescript::language_tsx(), - None, // + Some(Arc::new(typescript::TypeScriptLspAdapter)), ), ( "typescript", diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index 9ce3eab2f772d86fdcc7f7a717020480660a5ed5..cf4e2199676614de174a73647dbe67b5dfe67c97 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -3,7 +3,7 @@ use client::http::{self, HttpClient, Method}; use futures::{future::BoxFuture, FutureExt, StreamExt}; pub use language::*; use smol::fs::{self, File}; -use std::{path::PathBuf, str, sync::Arc}; +use std::{any::Any, path::PathBuf, str, sync::Arc}; use util::{ResultExt, TryFutureExt}; use super::GithubRelease; @@ -18,7 +18,7 @@ impl super::LspAdapter for CLspAdapter { fn fetch_latest_server_version( &self, http: Arc, - ) -> BoxFuture<'static, Result> { + ) -> BoxFuture<'static, Result>> { async move { let release = http .send( @@ -43,20 +43,21 @@ impl super::LspAdapter for CLspAdapter { .iter() .find(|asset| asset.name == asset_name) .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; - Ok(LspBinaryVersion { + Ok(Box::new(GitHubLspBinaryVersion { name: release.name, - url: Some(asset.browser_download_url.clone()), - }) + url: asset.browser_download_url.clone(), + }) as Box<_>) } .boxed() } fn fetch_server_binary( &self, - version: LspBinaryVersion, + version: Box, http: Arc, container_dir: PathBuf, ) -> BoxFuture<'static, Result> { + let version = version.downcast::().unwrap(); async move { let zip_path = container_dir.join(format!("clangd_{}.zip", version.name)); let version_dir = container_dir.join(format!("clangd_{}", version.name)); @@ -65,7 +66,7 @@ impl super::LspAdapter for CLspAdapter { if fs::metadata(&binary_path).await.is_err() { let response = http .send( - surf::RequestBuilder::new(Method::Get, version.url.unwrap()) + surf::RequestBuilder::new(Method::Get, version.url) .middleware(surf::middleware::Redirect::default()) .build(), ) diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs index bb7744714f415a4db7ee1df25cb0f65027a371b7..c1d0db2ed6d220773094a78c43d2df18c8317c51 100644 --- a/crates/zed/src/languages/json.rs +++ b/crates/zed/src/languages/json.rs @@ -1,12 +1,12 @@ use anyhow::{anyhow, Context, Result}; use client::http::HttpClient; use futures::{future::BoxFuture, FutureExt, StreamExt}; -use language::{LspAdapter, LspBinaryVersion}; +use language::LspAdapter; use serde::Deserialize; use serde_json::json; use smol::fs; -use std::{path::PathBuf, sync::Arc}; -use util::ResultExt; +use std::{any::Any, path::PathBuf, sync::Arc}; +use util::{ResultExt, TryFutureExt}; pub struct JsonLspAdapter; @@ -27,7 +27,7 @@ impl LspAdapter for JsonLspAdapter { fn fetch_latest_server_version( &self, _: Arc, - ) -> BoxFuture<'static, Result> { + ) -> BoxFuture<'static, Result>> { async move { #[derive(Deserialize)] struct NpmInfo { @@ -43,25 +43,24 @@ impl LspAdapter for JsonLspAdapter { } let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; - Ok(LspBinaryVersion { - name: info - .versions + Ok(Box::new( + info.versions .pop() .ok_or_else(|| anyhow!("no versions found in npm info"))?, - url: Default::default(), - }) + ) as Box<_>) } .boxed() } fn fetch_server_binary( &self, - version: LspBinaryVersion, + version: Box, _: Arc, container_dir: PathBuf, ) -> BoxFuture<'static, Result> { + let version = version.downcast::().unwrap(); async move { - let version_dir = container_dir.join(&version.name); + let version_dir = container_dir.join(version.as_str()); fs::create_dir_all(&version_dir) .await .context("failed to create version directory")?; @@ -71,7 +70,7 @@ impl LspAdapter for JsonLspAdapter { let output = smol::process::Command::new("npm") .current_dir(&version_dir) .arg("install") - .arg(format!("vscode-json-languageserver@{}", version.name)) + .arg(format!("vscode-json-languageserver@{}", version)) .output() .await .context("failed to run npm install")?; diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 2d4c6b3d3673c1117abbe86fcfc48044f283cf05..8b06c5cbd7c784752cd91fecded506a40f6f5423 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -6,7 +6,7 @@ pub use language::*; use lazy_static::lazy_static; use regex::Regex; use smol::fs::{self, File}; -use std::{borrow::Cow, env::consts, path::PathBuf, str, sync::Arc}; +use std::{any::Any, borrow::Cow, env::consts, path::PathBuf, str, sync::Arc}; use util::{ResultExt, TryFutureExt}; use super::GithubRelease; @@ -21,7 +21,7 @@ impl LspAdapter for RustLspAdapter { fn fetch_latest_server_version( &self, http: Arc, - ) -> BoxFuture<'static, Result> { + ) -> BoxFuture<'static, Result>> { async move { let release = http .send( @@ -46,27 +46,28 @@ impl LspAdapter for RustLspAdapter { .iter() .find(|asset| asset.name == asset_name) .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; - Ok(LspBinaryVersion { + Ok(Box::new(GitHubLspBinaryVersion { name: release.name, - url: Some(asset.browser_download_url.clone()), - }) + url: asset.browser_download_url.clone(), + }) as Box<_>) } .boxed() } fn fetch_server_binary( &self, - version: LspBinaryVersion, + version: Box, http: Arc, container_dir: PathBuf, ) -> BoxFuture<'static, Result> { async move { + let version = version.downcast::().unwrap(); let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name)); if fs::metadata(&destination_path).await.is_err() { let response = http .send( - surf::RequestBuilder::new(Method::Get, version.url.unwrap()) + surf::RequestBuilder::new(Method::Get, version.url) .middleware(surf::middleware::Redirect::default()) .build(), ) diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 59b7d225f9cb4dc1850e3a42280011dd37d7454d..f7547fdd4e651a03bc53028c591a6aa16b60878a 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -1,57 +1,86 @@ +use anyhow::{anyhow, Context, Result}; +use client::http::HttpClient; +use futures::{future::BoxFuture, FutureExt, StreamExt}; +use language::LspAdapter; +use serde::Deserialize; +use serde_json::json; +use smol::fs; +use std::{any::Any, path::PathBuf, sync::Arc}; +use util::{ResultExt, TryFutureExt}; + pub struct TypeScriptLspAdapter; impl TypeScriptLspAdapter { - const BIN_PATH: &'static str = - "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; + const BIN_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.js"; +} + +struct Versions { + typescript_version: String, + server_version: String, } -impl super::LspAdapter for TypeScriptLspAdapter { +impl LspAdapter for TypeScriptLspAdapter { fn name(&self) -> &'static str { "typescript-language-server" } fn server_args(&self) -> &[&str] { - &["--stdio"] + &["--stdio", "--tsserver-path", "node_modules/typescript/lib"] } fn fetch_latest_server_version( &self, _: Arc, - ) -> BoxFuture<'static, Result> { + ) -> BoxFuture<'static, Result>> { async move { #[derive(Deserialize)] struct NpmInfo { versions: Vec, } - let output = smol::process::Command::new("npm") - .args(["info", "vscode-json-languageserver", "--json"]) + let typescript_output = smol::process::Command::new("npm") + .args(["info", "typescript", "--json"]) + .output() + .await?; + if !typescript_output.status.success() { + Err(anyhow!("failed to execute npm info"))?; + } + let mut typescript_info: NpmInfo = serde_json::from_slice(&typescript_output.stdout)?; + + let server_output = smol::process::Command::new("npm") + .args(["info", "typescript-language-server", "--json"]) .output() .await?; - if !output.status.success() { + if !server_output.status.success() { Err(anyhow!("failed to execute npm info"))?; } - let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; + let mut server_info: NpmInfo = serde_json::from_slice(&server_output.stdout)?; - Ok(LspBinaryVersion { - name: info + Ok(Box::new(Versions { + typescript_version: typescript_info .versions .pop() - .ok_or_else(|| anyhow!("no versions found in npm info"))?, - url: Default::default(), - }) + .ok_or_else(|| anyhow!("no versions found in typescript npm info"))?, + server_version: server_info.versions.pop().ok_or_else(|| { + anyhow!("no versions found in typescript language server npm info") + })?, + }) as Box<_>) } .boxed() } fn fetch_server_binary( &self, - version: LspBinaryVersion, + versions: Box, _: Arc, container_dir: PathBuf, ) -> BoxFuture<'static, Result> { + let versions = versions.downcast::().unwrap(); async move { - let version_dir = container_dir.join(&version.name); + let version_dir = container_dir.join(&format!( + "typescript-{}:server-{}", + versions.typescript_version, versions.server_version + )); fs::create_dir_all(&version_dir) .await .context("failed to create version directory")?; @@ -61,12 +90,16 @@ impl super::LspAdapter for TypeScriptLspAdapter { let output = smol::process::Command::new("npm") .current_dir(&version_dir) .arg("install") - .arg(format!("vscode-json-languageserver@{}", version.name)) + .arg(format!("typescript@{}", versions.typescript_version)) + .arg(format!( + "typescript-language-server@{}", + versions.server_version + )) .output() .await .context("failed to run npm install")?; if !output.status.success() { - Err(anyhow!("failed to install vscode-json-languageserver"))?; + Err(anyhow!("failed to install typescript-language-server"))?; } if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { From 158d9879652b4cd24fb2b381b1e938b1543b1892 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 29 Mar 2022 16:57:18 -0700 Subject: [PATCH 07/68] Start work on allowing language servers to support multiple languages --- crates/language/src/language.rs | 32 ++++-- crates/project/src/lsp_command.rs | 23 ++-- crates/project/src/project.rs | 141 +++++++++++++------------ crates/rpc/proto/zed.proto | 2 +- crates/zed/src/languages/c.rs | 6 +- crates/zed/src/languages/json.rs | 6 +- crates/zed/src/languages/rust.rs | 4 +- crates/zed/src/languages/typescript.rs | 6 +- 8 files changed, 118 insertions(+), 102 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 6e400c4a6fa2e5a5f35ee84ee9339cba190a2741..8d573574fda99bf1f2c862794bba6049107ba0b4 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -8,7 +8,7 @@ mod tests; use anyhow::{anyhow, Context, Result}; use client::http::{self, HttpClient}; -use collections::HashSet; +use collections::{HashMap, HashSet}; use futures::{ future::{BoxFuture, Shared}, FutureExt, TryFutureExt, @@ -67,8 +67,11 @@ pub struct GitHubLspBinaryVersion { pub url: http::Url, } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct LanguageServerName(pub Arc); + pub trait LspAdapter: 'static + Send + Sync { - fn name(&self) -> &'static str; + fn name(&self) -> LanguageServerName; fn fetch_latest_server_version( &self, http: Arc, @@ -159,7 +162,6 @@ pub struct Language { pub(crate) config: LanguageConfig, pub(crate) grammar: Option>, pub(crate) adapter: Option>, - lsp_binary_path: Mutex>>>>>, } pub struct Grammar { @@ -186,6 +188,12 @@ pub struct LanguageRegistry { lsp_binary_statuses_tx: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, lsp_binary_statuses_rx: async_broadcast::Receiver<(Arc, LanguageServerBinaryStatus)>, login_shell_env_loaded: Shared>, + lsp_binary_paths: Mutex< + HashMap< + LanguageServerName, + Shared>>>, + >, + >, } impl LanguageRegistry { @@ -197,6 +205,7 @@ impl LanguageRegistry { lsp_binary_statuses_tx, lsp_binary_statuses_rx, login_shell_env_loaded: login_shell_env_loaded.shared(), + lsp_binary_paths: Default::default(), } } @@ -246,7 +255,7 @@ impl LanguageRegistry { } pub fn start_language_server( - &self, + self: &Arc, language: Arc, root_path: Arc, http_client: Arc, @@ -291,16 +300,18 @@ impl LanguageRegistry { .ok_or_else(|| anyhow!("language server download directory has not been assigned")) .log_err()?; + let this = self.clone(); let adapter = language.adapter.clone()?; let background = cx.background().clone(); let lsp_binary_statuses = self.lsp_binary_statuses_tx.clone(); let login_shell_env_loaded = self.login_shell_env_loaded.clone(); Some(cx.background().spawn(async move { login_shell_env_loaded.await; - let server_binary_path = language - .lsp_binary_path + let server_binary_path = this + .lsp_binary_paths .lock() - .get_or_insert_with(|| { + .entry(adapter.name()) + .or_insert_with(|| { get_server_binary_path( adapter.clone(), language.clone(), @@ -342,7 +353,7 @@ async fn get_server_binary_path( download_dir: Arc, statuses: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, ) -> Result { - let container_dir = download_dir.join(adapter.name()); + let container_dir = download_dir.join(adapter.name().0.as_ref()); if !container_dir.exists() { smol::fs::create_dir_all(&container_dir) .await @@ -415,10 +426,13 @@ impl Language { }) }), adapter: None, - lsp_binary_path: Default::default(), } } + pub fn lsp_adapter(&self) -> Option> { + self.adapter.clone() + } + pub fn with_highlights_query(mut self, source: &str) -> Result { let grammar = self .grammar diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 4867ada7cb0f86b124cc7c11f5a568df83236eb7..b6f007659dad840b3ee9145131fd522498f5524d 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -223,22 +223,19 @@ impl LspCommand for PerformRename { mut cx: AsyncAppContext, ) -> Result { if let Some(edit) = message { - let language_server = project + let (lsp_adapter, lsp_server) = project .read_with(&cx, |project, cx| { project .language_server_for_buffer(buffer.read(cx), cx) .cloned() }) .ok_or_else(|| anyhow!("no language server found for buffer"))?; - let language = buffer - .read_with(&cx, |buffer, _| buffer.language().cloned()) - .ok_or_else(|| anyhow!("no language for buffer"))?; Project::deserialize_workspace_edit( project, edit, self.push_to_history, - language.name(), - language_server, + lsp_adapter, + lsp_server, &mut cx, ) .await @@ -343,16 +340,13 @@ impl LspCommand for GetDefinition { mut cx: AsyncAppContext, ) -> Result> { let mut definitions = Vec::new(); - let language_server = project + let (lsp_adapter, language_server) = project .read_with(&cx, |project, cx| { project .language_server_for_buffer(buffer.read(cx), cx) .cloned() }) .ok_or_else(|| anyhow!("no language server found for buffer"))?; - let language = buffer - .read_with(&cx, |buffer, _| buffer.language().cloned()) - .ok_or_else(|| anyhow!("no language for buffer"))?; if let Some(message) = message { let mut unresolved_locations = Vec::new(); @@ -377,7 +371,7 @@ impl LspCommand for GetDefinition { .update(&mut cx, |this, cx| { this.open_local_buffer_via_lsp( target_uri, - language.name(), + lsp_adapter.clone(), language_server.clone(), cx, ) @@ -521,16 +515,13 @@ impl LspCommand for GetReferences { mut cx: AsyncAppContext, ) -> Result> { let mut references = Vec::new(); - let language_server = project + let (lsp_adapter, language_server) = project .read_with(&cx, |project, cx| { project .language_server_for_buffer(buffer.read(cx), cx) .cloned() }) .ok_or_else(|| anyhow!("no language server found for buffer"))?; - let language = buffer - .read_with(&cx, |buffer, _| buffer.language().cloned()) - .ok_or_else(|| anyhow!("no language for buffer"))?; if let Some(locations) = locations { for lsp_location in locations { @@ -538,7 +529,7 @@ impl LspCommand for GetReferences { .update(&mut cx, |this, cx| { this.open_local_buffer_via_lsp( lsp_location.uri, - language.name(), + lsp_adapter.clone(), language_server.clone(), cx, ) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index f4d5e9ee11e855cbfe43e8a05dd6ad9a06027faf..6f550d10206e1f90475937e34ed5940a6b78531b 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -18,8 +18,8 @@ use language::{ proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, range_from_lsp, Anchor, Bias, Buffer, CodeAction, CodeLabel, Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, File as _, Language, LanguageRegistry, - LocalFile, OffsetRangeExt, Operation, Patch, PointUtf16, TextBufferSnapshot, ToLspPosition, - ToOffset, ToPointUtf16, Transaction, + LanguageServerName, LocalFile, LspAdapter, OffsetRangeExt, Operation, Patch, PointUtf16, + TextBufferSnapshot, ToLspPosition, ToOffset, ToPointUtf16, Transaction, }; use lsp::{DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer}; use lsp_command::*; @@ -57,8 +57,10 @@ pub struct Project { worktrees: Vec, active_entry: Option, languages: Arc, - language_servers: HashMap<(WorktreeId, Arc), Arc>, - started_language_servers: HashMap<(WorktreeId, Arc), Task>>>, + language_servers: + HashMap<(WorktreeId, LanguageServerName), (Arc, Arc)>, + started_language_servers: + HashMap<(WorktreeId, LanguageServerName), Task>>>, language_server_statuses: BTreeMap, language_server_settings: Arc>, next_language_server_id: usize, @@ -185,7 +187,7 @@ pub struct DocumentHighlight { pub struct Symbol { pub source_worktree_id: WorktreeId, pub worktree_id: WorktreeId, - pub language_name: String, + pub language_server_name: LanguageServerName, pub path: PathBuf, pub label: CodeLabel, pub name: String, @@ -957,8 +959,8 @@ impl Project { fn open_local_buffer_via_lsp( &mut self, abs_path: lsp::Url, - lang_name: Arc, - lang_server: Arc, + lsp_adapter: Arc, + lsp_server: Arc, cx: &mut ModelContext, ) -> Task>> { cx.spawn(|this, mut cx| async move { @@ -976,8 +978,10 @@ impl Project { }) .await?; this.update(&mut cx, |this, cx| { - this.language_servers - .insert((worktree.read(cx).id(), lang_name), lang_server); + this.language_servers.insert( + (worktree.read(cx).id(), lsp_adapter.name()), + (lsp_adapter, lsp_server), + ); }); (worktree, PathBuf::new()) }; @@ -1120,7 +1124,7 @@ impl Project { } } - if let Some(server) = language_server { + if let Some((_, server)) = language_server { server .notify::( lsp::DidOpenTextDocumentParams { @@ -1153,7 +1157,7 @@ impl Project { if let Some(file) = File::from_dyn(buffer.file()) { if file.is_local() { let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap(); - if let Some(server) = this.language_server_for_buffer(buffer, cx) { + if let Some((_, server)) = this.language_server_for_buffer(buffer, cx) { server .notify::( lsp::DidCloseTextDocumentParams { @@ -1189,7 +1193,7 @@ impl Project { cx.background().spawn(request).detach_and_log_err(cx); } BufferEvent::Edited { .. } => { - let language_server = self + let (_, language_server) = self .language_server_for_buffer(buffer.read(cx), cx)? .clone(); let buffer = buffer.read(cx); @@ -1262,11 +1266,11 @@ impl Project { fn language_servers_for_worktree( &self, worktree_id: WorktreeId, - ) -> impl Iterator)> { + ) -> impl Iterator, Arc)> { self.language_servers.iter().filter_map( - move |((language_server_worktree_id, language_name), server)| { + move |((language_server_worktree_id, _), server)| { if *language_server_worktree_id == worktree_id { - Some((language_name.as_ref(), server)) + Some(server) } else { None } @@ -1302,7 +1306,12 @@ impl Project { language: Arc, cx: &mut ModelContext, ) { - let key = (worktree_id, language.name()); + let adapter = if let Some(adapter) = language.lsp_adapter() { + adapter + } else { + return; + }; + let key = (worktree_id, adapter.name()); self.started_language_servers .entry(key.clone()) .or_insert_with(|| { @@ -1416,7 +1425,7 @@ impl Project { let language_server = language_server.initialize().await.log_err()?; this.update(&mut cx, |this, cx| { this.language_servers - .insert(key.clone(), language_server.clone()); + .insert(key.clone(), (adapter, language_server.clone())); this.language_server_statuses.insert( server_id, LanguageServerStatus { @@ -1459,7 +1468,10 @@ impl Project { } else { continue; }; - if (file.worktree.read(cx).id(), language.name()) != key { + if file.worktree.read(cx).id() != key.0 + || language.lsp_adapter().map(|a| a.name()) + != Some(key.1.clone()) + { continue; } @@ -1675,7 +1687,7 @@ impl Project { } pub fn set_language_server_settings(&mut self, settings: serde_json::Value) { - for server in self.language_servers.values() { + for (_, server) in self.language_servers.values() { server .notify::( lsp::DidChangeConfigurationParams { @@ -1925,7 +1937,7 @@ impl Project { let buffer = buffer_handle.read(cx); if let Some(file) = File::from_dyn(buffer.file()) { if let Some(buffer_abs_path) = file.as_local().map(|f| f.abs_path(cx)) { - if let Some(server) = self.language_server_for_buffer(buffer, cx) { + if let Some((_, server)) = self.language_server_for_buffer(buffer, cx) { local_buffers.push((buffer_handle, buffer_abs_path, server.clone())); } } else { @@ -2062,25 +2074,24 @@ impl Project { pub fn symbols(&self, query: &str, cx: &mut ModelContext) -> Task>> { if self.is_local() { let mut language_servers = HashMap::default(); - for ((worktree_id, language_name), language_server) in self.language_servers.iter() { - if let Some((worktree, language)) = self + for ((worktree_id, _), (lsp_adapter, language_server)) in self.language_servers.iter() { + if let Some(worktree) = self .worktree_for_id(*worktree_id, cx) .and_then(|worktree| worktree.read(cx).as_local()) - .zip(self.languages.get_language(language_name)) { language_servers .entry(Arc::as_ptr(language_server)) .or_insert(( + lsp_adapter.clone(), language_server.clone(), *worktree_id, worktree.abs_path().clone(), - language.clone(), )); } } let mut requests = Vec::new(); - for (language_server, _, _, _) in language_servers.values() { + for (_, language_server, _, _) in language_servers.values() { requests.push(language_server.request::( lsp::WorkspaceSymbolParams { query: query.to_string(), @@ -2095,7 +2106,7 @@ impl Project { let mut symbols = Vec::new(); if let Some(this) = this.upgrade(&cx) { this.read_with(&cx, |this, cx| { - for ((_, source_worktree_id, worktree_abs_path, language), lsp_symbols) in + for ((adapter, _, source_worktree_id, worktree_abs_path), lsp_symbols) in language_servers.into_values().zip(responses) { symbols.extend(lsp_symbols.into_iter().flatten().filter_map( @@ -2112,8 +2123,13 @@ impl Project { path = relativize_path(&worktree_abs_path, &abs_path); } - let label = language - .label_for_symbol(&lsp_symbol.name, lsp_symbol.kind) + let label = this + .languages + .select_language(&path) + .and_then(|language| { + language + .label_for_symbol(&lsp_symbol.name, lsp_symbol.kind) + }) .unwrap_or_else(|| { CodeLabel::plain(lsp_symbol.name.clone(), None) }); @@ -2122,7 +2138,7 @@ impl Project { Some(Symbol { source_worktree_id, worktree_id, - language_name: language.name().to_string(), + language_server_name: adapter.name(), name: lsp_symbol.name, kind: lsp_symbol.kind, label, @@ -2169,9 +2185,9 @@ impl Project { cx: &mut ModelContext, ) -> Task>> { if self.is_local() { - let language_server = if let Some(server) = self.language_servers.get(&( + let (lsp_adapter, language_server) = if let Some(server) = self.language_servers.get(&( symbol.source_worktree_id, - Arc::from(symbol.language_name.as_str()), + symbol.language_server_name.clone(), )) { server.clone() } else { @@ -2196,12 +2212,7 @@ impl Project { return Task::ready(Err(anyhow!("invalid symbol path"))); }; - self.open_local_buffer_via_lsp( - symbol_uri, - Arc::from(symbol.language_name.as_str()), - language_server, - cx, - ) + self.open_local_buffer_via_lsp(symbol_uri, lsp_adapter, language_server, cx) } else if let Some(project_id) = self.remote_id() { let request = self.client.request(proto::OpenBufferForSymbol { project_id, @@ -2242,7 +2253,7 @@ impl Project { if worktree.read(cx).as_local().is_some() { let buffer_abs_path = buffer_abs_path.unwrap(); - let lang_server = + let (_, lang_server) = if let Some(server) = self.language_server_for_buffer(source_buffer, cx) { server.clone() } else { @@ -2356,7 +2367,8 @@ impl Project { let buffer_id = buffer.remote_id(); if self.is_local() { - let lang_server = if let Some(server) = self.language_server_for_buffer(buffer, cx) { + let (_, lang_server) = if let Some(server) = self.language_server_for_buffer(buffer, cx) + { server.clone() } else { return Task::ready(Ok(Default::default())); @@ -2447,7 +2459,8 @@ impl Project { if worktree.read(cx).as_local().is_some() { let buffer_abs_path = buffer_abs_path.unwrap(); - let lang_server = if let Some(server) = self.language_server_for_buffer(buffer, cx) { + let (_, lang_server) = if let Some(server) = self.language_server_for_buffer(buffer, cx) + { server.clone() } else { return Task::ready(Ok(Default::default())); @@ -2534,16 +2547,12 @@ impl Project { ) -> Task> { if self.is_local() { let buffer = buffer_handle.read(cx); - let lang_name = if let Some(lang) = buffer.language() { - lang.name() - } else { - return Task::ready(Ok(Default::default())); - }; - let lang_server = if let Some(server) = self.language_server_for_buffer(buffer, cx) { - server.clone() - } else { - return Task::ready(Ok(Default::default())); - }; + let (lsp_adapter, lang_server) = + if let Some(server) = self.language_server_for_buffer(buffer, cx) { + server.clone() + } else { + return Task::ready(Ok(Default::default())); + }; let range = action.range.to_point_utf16(buffer); cx.spawn(|this, mut cx| async move { @@ -2580,7 +2589,7 @@ impl Project { this, edit, push_to_history, - lang_name, + lsp_adapter, lang_server, &mut cx, ) @@ -2616,7 +2625,7 @@ impl Project { this: ModelHandle, edit: lsp::WorkspaceEdit, push_to_history: bool, - language_name: Arc, + lsp_adapter: Arc, language_server: Arc, cx: &mut AsyncAppContext, ) -> Result { @@ -2693,7 +2702,7 @@ impl Project { .update(cx, |this, cx| { this.open_local_buffer_via_lsp( op.text_document.uri, - language_name.clone(), + lsp_adapter.clone(), language_server.clone(), cx, ) @@ -2988,7 +2997,7 @@ impl Project { let buffer = buffer_handle.read(cx); if self.is_local() { let file = File::from_dyn(buffer.file()).and_then(File::as_local); - if let Some((file, language_server)) = + if let Some((file, (_, language_server))) = file.zip(self.language_server_for_buffer(buffer, cx).cloned()) { let lsp_params = request.to_lsp(&file.abs_path(cx), cx); @@ -4086,9 +4095,8 @@ impl Project { } fn deserialize_symbol(&self, serialized_symbol: proto::Symbol) -> Result { - let language = self - .languages - .get_language(&serialized_symbol.language_name); + let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id); + let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id); let start = serialized_symbol .start .ok_or_else(|| anyhow!("invalid start"))?; @@ -4096,15 +4104,17 @@ impl Project { .end .ok_or_else(|| anyhow!("invalid end"))?; let kind = unsafe { mem::transmute(serialized_symbol.kind) }; + let path = PathBuf::from(serialized_symbol.path); + let language = self.languages.select_language(&path); Ok(Symbol { - source_worktree_id: WorktreeId::from_proto(serialized_symbol.source_worktree_id), - worktree_id: WorktreeId::from_proto(serialized_symbol.worktree_id), - language_name: serialized_symbol.language_name.clone(), + source_worktree_id, + worktree_id, + language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()), label: language .and_then(|language| language.label_for_symbol(&serialized_symbol.name, kind)) .unwrap_or_else(|| CodeLabel::plain(serialized_symbol.name.clone(), None)), name: serialized_symbol.name, - path: PathBuf::from(serialized_symbol.path), + path, range: PointUtf16::new(start.row, start.column)..PointUtf16::new(end.row, end.column), kind, signature: serialized_symbol @@ -4349,10 +4359,11 @@ impl Project { &self, buffer: &Buffer, cx: &AppContext, - ) -> Option<&Arc> { + ) -> Option<&(Arc, Arc)> { if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) { let worktree_id = file.worktree_id(cx); - self.language_servers.get(&(worktree_id, language.name())) + self.language_servers + .get(&(worktree_id, language.lsp_adapter()?.name())) } else { None } @@ -4466,7 +4477,7 @@ impl Entity for Project { let shutdown_futures = self .language_servers .drain() - .filter_map(|(_, server)| server.shutdown()) + .filter_map(|(_, (_, server))| server.shutdown()) .collect::>(); Some( async move { @@ -4537,7 +4548,7 @@ fn serialize_symbol(symbol: &Symbol) -> proto::Symbol { proto::Symbol { source_worktree_id: symbol.source_worktree_id.to_proto(), worktree_id: symbol.worktree_id.to_proto(), - language_name: symbol.language_name.clone(), + language_server_name: symbol.language_server_name.0.to_string(), name: symbol.name.clone(), kind: unsafe { mem::transmute(symbol.kind) }, path: symbol.path.to_string_lossy().to_string(), diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 9d25e66190b14bc7d4624885ec7da3dc57acb61b..cef0e60f0fe3bea6d90341954e6be3f923187a29 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -229,7 +229,7 @@ message GetProjectSymbolsResponse { message Symbol { uint64 source_worktree_id = 1; uint64 worktree_id = 2; - string language_name = 3; + string language_server_name = 3; string name = 4; int32 kind = 5; string path = 6; diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index cf4e2199676614de174a73647dbe67b5dfe67c97..56994db4251d995d347cb248279e52e3272d84d5 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -3,7 +3,7 @@ use client::http::{self, HttpClient, Method}; use futures::{future::BoxFuture, FutureExt, StreamExt}; pub use language::*; use smol::fs::{self, File}; -use std::{any::Any, path::PathBuf, str, sync::Arc}; +use std::{any::Any, path::PathBuf, sync::Arc}; use util::{ResultExt, TryFutureExt}; use super::GithubRelease; @@ -11,8 +11,8 @@ use super::GithubRelease; pub struct CLspAdapter; impl super::LspAdapter for CLspAdapter { - fn name(&self) -> &'static str { - "clangd" + fn name(&self) -> LanguageServerName { + LanguageServerName("clangd".into()) } fn fetch_latest_server_version( diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs index c1d0db2ed6d220773094a78c43d2df18c8317c51..4069413f11129f826add608995bf5c792db709d1 100644 --- a/crates/zed/src/languages/json.rs +++ b/crates/zed/src/languages/json.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Context, Result}; use client::http::HttpClient; use futures::{future::BoxFuture, FutureExt, StreamExt}; -use language::LspAdapter; +use language::{LanguageServerName, LspAdapter}; use serde::Deserialize; use serde_json::json; use smol::fs; @@ -16,8 +16,8 @@ impl JsonLspAdapter { } impl LspAdapter for JsonLspAdapter { - fn name(&self) -> &'static str { - "vscode-json-languageserver" + fn name(&self) -> LanguageServerName { + LanguageServerName("vscode-json-languageserver".into()) } fn server_args(&self) -> &[&str] { diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 8b06c5cbd7c784752cd91fecded506a40f6f5423..4034e5effa32b216cfcd22dc3f91c5aa1ce3cb69 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -14,8 +14,8 @@ use super::GithubRelease; pub struct RustLspAdapter; impl LspAdapter for RustLspAdapter { - fn name(&self) -> &'static str { - "rust-analyzer" + fn name(&self) -> LanguageServerName { + LanguageServerName("rust-analyzer".into()) } fn fetch_latest_server_version( diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index f7547fdd4e651a03bc53028c591a6aa16b60878a..4d7af34c38cf2c35ed030136c3f75395efeb9d2a 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Context, Result}; use client::http::HttpClient; use futures::{future::BoxFuture, FutureExt, StreamExt}; -use language::LspAdapter; +use language::{LanguageServerName, LspAdapter}; use serde::Deserialize; use serde_json::json; use smol::fs; @@ -20,8 +20,8 @@ struct Versions { } impl LspAdapter for TypeScriptLspAdapter { - fn name(&self) -> &'static str { - "typescript-language-server" + fn name(&self) -> LanguageServerName { + LanguageServerName("typescript-language-server".into()) } fn server_args(&self) -> &[&str] { From ebc711f9f500bd5c10d774659e6d3d0b6f078c27 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 29 Mar 2022 17:54:29 -0700 Subject: [PATCH 08/68] Restructure fake language server setup Replace FakeLanguageServerConfig with FakeLanguageServerAdapter --- crates/editor/src/editor.rs | 51 ++- crates/language/src/language.rs | 101 +++-- crates/project/src/project.rs | 124 +++--- crates/server/src/rpc.rs | 715 ++++++++++++++++---------------- 4 files changed, 496 insertions(+), 495 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index dac7adfdf823f2d18e16d0b6d1a27a4f7c321173..b9428fc1f5acbe5d1bf1a852cb2796320722e515 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -6438,13 +6438,12 @@ pub fn styled_runs_for_code_label<'a>( #[cfg(test)] mod tests { - use super::*; use gpui::{ geometry::rect::RectF, platform::{WindowBounds, WindowOptions}, }; - use language::{LanguageConfig, LanguageServerConfig}; + use language::{FakeLspAdapter, LanguageConfig}; use lsp::FakeLanguageServer; use project::FakeFs; use smol::stream::StreamExt; @@ -8880,26 +8879,27 @@ mod tests { cx.foreground().forbid_parking(); cx.update(populate_settings); - let (mut language_server_config, mut fake_servers) = LanguageServerConfig::fake(); - language_server_config.set_fake_capabilities(lsp::ServerCapabilities { - document_formatting_provider: Some(lsp::OneOf::Left(true)), - ..Default::default() - }); - let language = Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + capabilities: lsp::ServerCapabilities { + document_formatting_provider: Some(lsp::OneOf::Left(true)), + ..Default::default() + }, + ..Default::default() + }); let fs = FakeFs::new(cx.background().clone()); fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, cx); - project.update(cx, |project, _| project.languages().add(language)); + project.update(cx, |project, _| project.languages().add(Arc::new(language))); let worktree_id = project .update(cx, |project, cx| { @@ -8913,6 +8913,8 @@ mod tests { .update(cx, |project, cx| project.open_buffer((worktree_id, ""), cx)) .await .unwrap(); + + cx.foreground().start_waiting(); let mut fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); @@ -8934,6 +8936,7 @@ mod tests { }) .next() .await; + cx.foreground().start_waiting(); save.await.unwrap(); assert_eq!( editor.read_with(cx, |editor, cx| editor.text(cx)), @@ -8955,6 +8958,7 @@ mod tests { }); let save = cx.update(|cx| editor.save(project.clone(), cx)); cx.foreground().advance_clock(items::FORMAT_TIMEOUT); + cx.foreground().start_waiting(); save.await.unwrap(); assert_eq!( editor.read_with(cx, |editor, cx| editor.text(cx)), @@ -8967,23 +8971,24 @@ mod tests { async fn test_completion(cx: &mut gpui::TestAppContext) { cx.update(populate_settings); - let (mut language_server_config, mut fake_servers) = LanguageServerConfig::fake(); - language_server_config.set_fake_capabilities(lsp::ServerCapabilities { - completion_provider: Some(lsp::CompletionOptions { - trigger_characters: Some(vec![".".to_string(), ":".to_string()]), - ..Default::default() - }), - ..Default::default() - }); - let language = Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + capabilities: lsp::ServerCapabilities { + completion_provider: Some(lsp::CompletionOptions { + trigger_characters: Some(vec![".".to_string(), ":".to_string()]), + ..Default::default() + }), + ..Default::default() + }, + ..Default::default() + }); let text = " one @@ -8996,7 +9001,7 @@ mod tests { fs.insert_file("/file.rs", text).await; let project = Project::test(fs, cx); - project.update(cx, |project, _| project.languages().add(language)); + project.update(cx, |project, _| project.languages().add(Arc::new(language))); let worktree_id = project .update(cx, |project, cx| { diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 8d573574fda99bf1f2c862794bba6049107ba0b4..a98f1a9845c28f4fed6198a270a1f4a20e74b7c1 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -138,16 +138,13 @@ impl Default for LanguageConfig { pub struct LanguageServerConfig { pub disk_based_diagnostic_sources: HashSet, pub disk_based_diagnostics_progress_token: Option, - #[cfg(any(test, feature = "test-support"))] - #[serde(skip)] - fake_config: Option, } #[cfg(any(test, feature = "test-support"))] -struct FakeLanguageServerConfig { - servers_tx: mpsc::UnboundedSender, - capabilities: lsp::ServerCapabilities, - initializer: Option>, +pub struct FakeLspAdapter { + pub name: &'static str, + pub capabilities: lsp::ServerCapabilities, + pub initializer: Option>, } #[derive(Clone, Debug, Deserialize)] @@ -162,6 +159,12 @@ pub struct Language { pub(crate) config: LanguageConfig, pub(crate) grammar: Option>, pub(crate) adapter: Option>, + + #[cfg(any(test, feature = "test-support"))] + fake_adapter: Option<( + mpsc::UnboundedSender, + Arc, + )>, } pub struct Grammar { @@ -262,26 +265,22 @@ impl LanguageRegistry { cx: &mut MutableAppContext, ) -> Option>> { #[cfg(any(test, feature = "test-support"))] - if language.config.language_server.fake_config.is_some() { + if language.fake_adapter.is_some() { let language = language.clone(); return Some(cx.spawn(|mut cx| async move { - let fake_config = language - .config - .language_server - .fake_config - .as_ref() - .unwrap(); + let (servers_tx, fake_adapter) = language.fake_adapter.as_ref().unwrap(); let (server, mut fake_server) = cx.update(|cx| { lsp::LanguageServer::fake_with_capabilities( - fake_config.capabilities.clone(), + fake_adapter.capabilities.clone(), cx, ) }); - if let Some(initializer) = &fake_config.initializer { + + if let Some(initializer) = &fake_adapter.initializer { initializer(&mut fake_server); } - let servers_tx = fake_config.servers_tx.clone(); + let servers_tx = servers_tx.clone(); cx.background() .spawn(async move { fake_server @@ -426,6 +425,9 @@ impl Language { }) }), adapter: None, + + #[cfg(any(test, feature = "test-support"))] + fake_adapter: None, } } @@ -478,6 +480,18 @@ impl Language { self } + #[cfg(any(test, feature = "test-support"))] + pub fn set_fake_lsp_adapter( + &mut self, + fake_lsp_adapter: FakeLspAdapter, + ) -> mpsc::UnboundedReceiver { + let (servers_tx, servers_rx) = mpsc::unbounded(); + let adapter = Arc::new(fake_lsp_adapter); + self.fake_adapter = Some((servers_tx, adapter.clone())); + self.adapter = Some(adapter); + servers_rx + } + pub fn name(&self) -> Arc { self.config.name.clone() } @@ -601,33 +615,42 @@ impl CodeLabel { } #[cfg(any(test, feature = "test-support"))] -impl LanguageServerConfig { - pub fn fake() -> (Self, mpsc::UnboundedReceiver) { - let (servers_tx, servers_rx) = mpsc::unbounded(); - ( - Self { - fake_config: Some(FakeLanguageServerConfig { - servers_tx, - capabilities: lsp::LanguageServer::full_capabilities(), - initializer: None, - }), - disk_based_diagnostics_progress_token: Some("fakeServer/check".to_string()), - ..Default::default() - }, - servers_rx, - ) +impl Default for FakeLspAdapter { + fn default() -> Self { + Self { + name: "the-fake-language-server", + capabilities: lsp::LanguageServer::full_capabilities(), + initializer: None, + } } +} - pub fn set_fake_capabilities(&mut self, capabilities: lsp::ServerCapabilities) { - self.fake_config.as_mut().unwrap().capabilities = capabilities; +impl LspAdapter for FakeLspAdapter { + fn name(&self) -> LanguageServerName { + LanguageServerName(self.name.into()) } - pub fn set_fake_initializer( - &mut self, - initializer: impl 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer), - ) { - self.fake_config.as_mut().unwrap().initializer = Some(Box::new(initializer)); + fn fetch_latest_server_version( + &self, + _: Arc, + ) -> BoxFuture<'static, Result>> { + unreachable!(); } + + fn fetch_server_binary( + &self, + _: Box, + _: Arc, + _: PathBuf, + ) -> BoxFuture<'static, Result> { + unreachable!(); + } + + fn cached_server_binary(&self, _: PathBuf) -> BoxFuture<'static, Option> { + unreachable!(); + } + + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} } impl ToLspPosition for PointUtf16 { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 6f550d10206e1f90475937e34ed5940a6b78531b..1dd0f907f702db274cf580e6f2be829c79fc2e1e 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4606,8 +4606,8 @@ mod tests { use futures::StreamExt; use gpui::test::subscribe; use language::{ - tree_sitter_rust, Diagnostic, LanguageConfig, LanguageServerConfig, OffsetRangeExt, Point, - ToPoint, + tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, LanguageServerConfig, + OffsetRangeExt, Point, ToPoint, }; use lsp::Url; use serde_json::json; @@ -4683,41 +4683,44 @@ mod tests { async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let (mut rust_lsp_config, mut fake_rust_servers) = LanguageServerConfig::fake(); - let (mut json_lsp_config, mut fake_json_servers) = LanguageServerConfig::fake(); - rust_lsp_config.set_fake_capabilities(lsp::ServerCapabilities { - completion_provider: Some(lsp::CompletionOptions { - trigger_characters: Some(vec![".".to_string(), "::".to_string()]), - ..Default::default() - }), - ..Default::default() - }); - json_lsp_config.set_fake_capabilities(lsp::ServerCapabilities { - completion_provider: Some(lsp::CompletionOptions { - trigger_characters: Some(vec![":".to_string()]), - ..Default::default() - }), - ..Default::default() - }); - - let rust_language = Arc::new(Language::new( + let mut rust_language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: rust_lsp_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); - let json_language = Arc::new(Language::new( + ); + let mut json_language = Language::new( LanguageConfig { name: "JSON".into(), path_suffixes: vec!["json".to_string()], - language_server: json_lsp_config, ..Default::default() }, None, - )); + ); + let mut fake_rust_servers = rust_language.set_fake_lsp_adapter(FakeLspAdapter { + name: "the-rust-language-server", + capabilities: lsp::ServerCapabilities { + completion_provider: Some(lsp::CompletionOptions { + trigger_characters: Some(vec![".".to_string(), "::".to_string()]), + ..Default::default() + }), + ..Default::default() + }, + ..Default::default() + }); + let mut fake_json_servers = json_language.set_fake_lsp_adapter(FakeLspAdapter { + name: "the-json-language-server", + capabilities: lsp::ServerCapabilities { + completion_provider: Some(lsp::CompletionOptions { + trigger_characters: Some(vec![":".to_string()]), + ..Default::default() + }), + ..Default::default() + }, + ..Default::default() + }); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -4733,8 +4736,8 @@ mod tests { let project = Project::test(fs, cx); project.update(cx, |project, _| { - project.languages.add(rust_language); - project.languages.add(json_language); + project.languages.add(Arc::new(rust_language)); + project.languages.add(Arc::new(json_language)); }); let worktree_id = project @@ -4903,21 +4906,20 @@ mod tests { async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let (language_server_config, mut fake_servers) = LanguageServerConfig::fake(); - let progress_token = language_server_config - .disk_based_diagnostics_progress_token - .clone() - .unwrap(); - - let language = Arc::new(Language::new( + let progress_token = "the-progress-token".to_string(); + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, + language_server: LanguageServerConfig { + disk_based_diagnostics_progress_token: Some(progress_token.clone()), + ..Default::default() + }, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -4930,7 +4932,7 @@ mod tests { .await; let project = Project::test(fs, cx); - project.update(cx, |project, _| project.languages.add(language)); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); let (tree, _) = project .update(cx, |project, cx| { @@ -5022,19 +5024,20 @@ mod tests { async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let (mut lsp_config, mut fake_servers) = LanguageServerConfig::fake(); - lsp_config - .disk_based_diagnostic_sources - .insert("disk".to_string()); - let language = Arc::new(Language::new( + // let (mut lsp_config, mut fake_servers) = LanguageServerConfig::fake(); + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: lsp_config, + language_server: LanguageServerConfig { + disk_based_diagnostic_sources: ["disk".to_string()].into_iter().collect(), + ..Default::default() + }, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); let text = " fn a() { A } @@ -5047,7 +5050,7 @@ mod tests { fs.insert_tree("/dir", json!({ "a.rs": text })).await; let project = Project::test(fs, cx); - project.update(cx, |project, _| project.languages.add(language)); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); let worktree_id = project .update(cx, |project, cx| { @@ -5396,16 +5399,15 @@ mod tests { async fn test_edits_from_lsp_with_past_version(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let (lsp_config, mut fake_servers) = LanguageServerConfig::fake(); - let language = Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: lsp_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); let text = " fn a() { @@ -5430,7 +5432,7 @@ mod tests { .await; let project = Project::test(fs, cx); - project.update(cx, |project, _| project.languages.add(language)); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); let worktree_id = project .update(cx, |project, cx| { @@ -5746,16 +5748,15 @@ mod tests { #[gpui::test] async fn test_definition(cx: &mut gpui::TestAppContext) { - let (language_server_config, mut fake_servers) = LanguageServerConfig::fake(); - let language = Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -5768,9 +5769,7 @@ mod tests { .await; let project = Project::test(fs, cx); - project.update(cx, |project, _| { - Arc::get_mut(&mut project.languages).unwrap().add(language); - }); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); let (tree, _) = project .update(cx, |project, cx| { @@ -6682,16 +6681,15 @@ mod tests { async fn test_rename(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let (language_server_config, mut fake_servers) = LanguageServerConfig::fake(); - let language = Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), - )); + ); + let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -6704,9 +6702,7 @@ mod tests { .await; let project = Project::test(fs.clone(), cx); - project.update(cx, |project, _| { - Arc::get_mut(&mut project.languages).unwrap().add(language); - }); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); let (tree, _) = project .update(cx, |project, cx| { diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index b329839de2b80912ff48299a69407ef5d8e42c4f..0f8720c673b731e1f75c63650f46ea0ac7f1aa33 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -1088,10 +1088,10 @@ mod tests { }; use gpui::{executor, geometry::vector::vec2f, ModelHandle, TestAppContext, ViewHandle}; use language::{ - tree_sitter_rust, Diagnostic, DiagnosticEntry, Language, LanguageConfig, LanguageRegistry, - LanguageServerConfig, OffsetRangeExt, Point, ToLspPosition, + tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, LanguageConfig, + LanguageRegistry, OffsetRangeExt, Point, ToLspPosition, }; - use lsp; + use lsp::{self, FakeLanguageServer}; use parking_lot::Mutex; use postage::barrier; use project::{ @@ -2039,22 +2039,20 @@ mod tests { cx_b: &mut TestAppContext, ) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -2261,29 +2259,29 @@ mod tests { cx_b: &mut TestAppContext, ) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); // Set up a fake language server. - let (mut language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - language_server_config.set_fake_capabilities(lsp::ServerCapabilities { - completion_provider: Some(lsp::CompletionOptions { - trigger_characters: Some(vec![".".to_string()]), + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], ..Default::default() - }), + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + capabilities: lsp::ServerCapabilities { + completion_provider: Some(lsp::CompletionOptions { + trigger_characters: Some(vec![".".to_string()]), + ..Default::default() + }), + ..Default::default() + }, ..Default::default() }); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -2463,22 +2461,20 @@ mod tests { #[gpui::test(iterations = 10)] async fn test_formatting_buffer(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -2563,7 +2559,7 @@ mod tests { #[gpui::test(iterations = 10)] async fn test_definition(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); fs.insert_tree( "/root-1", @@ -2582,18 +2578,16 @@ mod tests { .await; // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -2705,7 +2699,7 @@ mod tests { #[gpui::test(iterations = 10)] async fn test_references(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); fs.insert_tree( "/root-1", @@ -2725,18 +2719,16 @@ mod tests { .await; // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -2967,16 +2959,16 @@ mod tests { .await; // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - lang_registry.add(Arc::new(Language::new( + let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, ..Default::default() }, Some(tree_sitter_rust::language()), - ))); + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -3092,7 +3084,7 @@ mod tests { #[gpui::test(iterations = 10)] async fn test_project_symbols(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); fs.insert_tree( "/code", @@ -3112,18 +3104,16 @@ mod tests { .await; // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -3231,7 +3221,7 @@ mod tests { mut rng: StdRng, ) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); fs.insert_tree( "/root", @@ -3244,19 +3234,16 @@ mod tests { .await; // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -3337,23 +3324,21 @@ mod tests { cx_b: &mut TestAppContext, ) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); cx_b.update(|cx| editor::init(cx)); // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -3573,23 +3558,21 @@ mod tests { #[gpui::test(iterations = 10)] async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - let mut lang_registry = Arc::new(LanguageRegistry::test()); + let lang_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx_a.background()); cx_b.update(|cx| editor::init(cx)); // Set up a fake language server. - let (language_server_config, mut fake_language_servers) = LanguageServerConfig::fake(); - Arc::get_mut(&mut lang_registry) - .unwrap() - .add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - Some(tree_sitter_rust::language()), - ))); + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + lang_registry.add(Arc::new(language)); // Connect to a server as 2 clients. let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; @@ -4838,7 +4821,7 @@ mod tests { let rng = Arc::new(Mutex::new(rng)); let guest_lang_registry = Arc::new(LanguageRegistry::test()); - let (language_server_config, _fake_language_servers) = LanguageServerConfig::fake(); + let host_language_registry = Arc::new(LanguageRegistry::test()); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -4852,6 +4835,7 @@ mod tests { let operations = Rc::new(Cell::new(0)); let mut server = TestServer::start(cx.foreground(), cx.background()).await; let mut clients = Vec::new(); + let files = Arc::new(Mutex::new(Vec::new())); let mut next_entity_id = 100000; let mut host_cx = TestAppContext::new( @@ -4868,7 +4852,7 @@ mod tests { Project::local( host.client.clone(), host.user_store.clone(), - Arc::new(LanguageRegistry::test()), + host_language_registry.clone(), fs.clone(), cx, ) @@ -4891,9 +4875,138 @@ mod tests { .await .unwrap(); + // Set up fake language servers. + let mut language = Language::new( + LanguageConfig { + name: "Rust".into(), + path_suffixes: vec!["rs".to_string()], + ..Default::default() + }, + None, + ); + let _fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + name: "the-fake-language-server", + capabilities: lsp::LanguageServer::full_capabilities(), + initializer: Some(Box::new({ + let rng = rng.clone(); + let files = files.clone(); + let project = host_project.downgrade(); + move |fake_server: &mut FakeLanguageServer| { + fake_server.handle_request::( + |_, _| async move { + Some(lsp::CompletionResponse::Array(vec![lsp::CompletionItem { + text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { + range: lsp::Range::new( + lsp::Position::new(0, 0), + lsp::Position::new(0, 0), + ), + new_text: "the-new-text".to_string(), + })), + ..Default::default() + }])) + }, + ); + + fake_server.handle_request::( + |_, _| async move { + Some(vec![lsp::CodeActionOrCommand::CodeAction( + lsp::CodeAction { + title: "the-code-action".to_string(), + ..Default::default() + }, + )]) + }, + ); + + fake_server.handle_request::( + |params, _| async move { + Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( + params.position, + params.position, + ))) + }, + ); + + fake_server.handle_request::({ + let files = files.clone(); + let rng = rng.clone(); + move |_, _| { + let files = files.clone(); + let rng = rng.clone(); + async move { + let files = files.lock(); + let mut rng = rng.lock(); + let count = rng.gen_range::(1..3); + let files = (0..count) + .map(|_| files.choose(&mut *rng).unwrap()) + .collect::>(); + log::info!("LSP: Returning definitions in files {:?}", &files); + Some(lsp::GotoDefinitionResponse::Array( + files + .into_iter() + .map(|file| lsp::Location { + uri: lsp::Url::from_file_path(file).unwrap(), + range: Default::default(), + }) + .collect(), + )) + } + } + }); + + fake_server.handle_request::({ + let rng = rng.clone(); + let project = project.clone(); + move |params, mut cx| { + let highlights = if let Some(project) = project.upgrade(&cx) { + project.update(&mut cx, |project, cx| { + let path = params + .text_document_position_params + .text_document + .uri + .to_file_path() + .unwrap(); + let (worktree, relative_path) = + project.find_local_worktree(&path, cx)?; + let project_path = + ProjectPath::from((worktree.read(cx).id(), relative_path)); + let buffer = + project.get_open_buffer(&project_path, cx)?.read(cx); + + let mut highlights = Vec::new(); + let highlight_count = rng.lock().gen_range(1..=5); + let mut prev_end = 0; + for _ in 0..highlight_count { + let range = + buffer.random_byte_range(prev_end, &mut *rng.lock()); + let start = buffer + .offset_to_point_utf16(range.start) + .to_lsp_position(); + let end = buffer + .offset_to_point_utf16(range.end) + .to_lsp_position(); + highlights.push(lsp::DocumentHighlight { + range: lsp::Range::new(start, end), + kind: Some(lsp::DocumentHighlightKind::READ), + }); + prev_end = range.end; + } + Some(highlights) + }) + } else { + None + }; + async move { highlights } + } + }); + } + })), + }); + host_language_registry.add(Arc::new(language)); + clients.push(cx.foreground().spawn(host.simulate_host( host_project, - language_server_config, + files, operations.clone(), max_operations, rng.clone(), @@ -5324,264 +5437,128 @@ mod tests { }) } - fn simulate_host( + async fn simulate_host( mut self, project: ModelHandle, - mut language_server_config: LanguageServerConfig, + files: Arc>>, operations: Rc>, max_operations: usize, rng: Arc>, mut cx: TestAppContext, - ) -> impl Future { - let files: Arc>> = Default::default(); - - // Set up a fake language server. - language_server_config.set_fake_initializer({ - let rng = rng.clone(); - let files = files.clone(); - let project = project.downgrade(); - move |fake_server| { - fake_server.handle_request::( - |_, _| async move { - Some(lsp::CompletionResponse::Array(vec![lsp::CompletionItem { - text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { - range: lsp::Range::new( - lsp::Position::new(0, 0), - lsp::Position::new(0, 0), - ), - new_text: "the-new-text".to_string(), - })), - ..Default::default() - }])) - }, - ); - - fake_server.handle_request::( - |_, _| async move { - Some(vec![lsp::CodeActionOrCommand::CodeAction( - lsp::CodeAction { - title: "the-code-action".to_string(), - ..Default::default() - }, - )]) - }, - ); - - fake_server.handle_request::( - |params, _| async move { - Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( - params.position, - params.position, - ))) - }, - ); + ) -> (Self, TestAppContext) { + let fs = project.read_with(&cx, |project, _| project.fs().clone()); + while operations.get() < max_operations { + operations.set(operations.get() + 1); - fake_server.handle_request::({ - let files = files.clone(); - let rng = rng.clone(); - move |_, _| { - let files = files.clone(); - let rng = rng.clone(); - async move { - let files = files.lock(); - let mut rng = rng.lock(); - let count = rng.gen_range::(1..3); - let files = (0..count) - .map(|_| files.choose(&mut *rng).unwrap()) - .collect::>(); - log::info!("LSP: Returning definitions in files {:?}", &files); - Some(lsp::GotoDefinitionResponse::Array( - files - .into_iter() - .map(|file| lsp::Location { - uri: lsp::Url::from_file_path(file).unwrap(), - range: Default::default(), - }) - .collect(), - )) + let distribution = rng.lock().gen_range::(0..100); + match distribution { + 0..=20 if !files.lock().is_empty() => { + let path = files.lock().choose(&mut *rng.lock()).unwrap().clone(); + let mut path = path.as_path(); + while let Some(parent_path) = path.parent() { + path = parent_path; + if rng.lock().gen() { + break; } } - }); - fake_server.handle_request::({ - let rng = rng.clone(); - let project = project.clone(); - move |params, mut cx| { - let highlights = if let Some(project) = project.upgrade(&cx) { - project.update(&mut cx, |project, cx| { - let path = params - .text_document_position_params - .text_document - .uri - .to_file_path() - .unwrap(); - let (worktree, relative_path) = - project.find_local_worktree(&path, cx)?; - let project_path = - ProjectPath::from((worktree.read(cx).id(), relative_path)); - let buffer = - project.get_open_buffer(&project_path, cx)?.read(cx); - - let mut highlights = Vec::new(); - let highlight_count = rng.lock().gen_range(1..=5); - let mut prev_end = 0; - for _ in 0..highlight_count { - let range = - buffer.random_byte_range(prev_end, &mut *rng.lock()); - let start = buffer - .offset_to_point_utf16(range.start) - .to_lsp_position(); - let end = buffer - .offset_to_point_utf16(range.end) - .to_lsp_position(); - highlights.push(lsp::DocumentHighlight { - range: lsp::Range::new(start, end), - kind: Some(lsp::DocumentHighlightKind::READ), - }); - prev_end = range.end; - } - Some(highlights) - }) - } else { - None - }; - async move { highlights } + log::info!("Host: find/create local worktree {:?}", path); + let find_or_create_worktree = project.update(&mut cx, |project, cx| { + project.find_or_create_local_worktree(path, true, cx) + }); + let find_or_create_worktree = async move { + find_or_create_worktree.await.unwrap(); + }; + if rng.lock().gen() { + cx.background().spawn(find_or_create_worktree).detach(); + } else { + find_or_create_worktree.await; } - }); - } - }); - - project.update(&mut cx, |project, _| { - project.languages().add(Arc::new(Language::new( - LanguageConfig { - name: "Rust".into(), - path_suffixes: vec!["rs".to_string()], - language_server: language_server_config, - ..Default::default() - }, - None, - ))); - }); - - async move { - let fs = project.read_with(&cx, |project, _| project.fs().clone()); - while operations.get() < max_operations { - operations.set(operations.get() + 1); - - let distribution = rng.lock().gen_range::(0..100); - match distribution { - 0..=20 if !files.lock().is_empty() => { - let path = files.lock().choose(&mut *rng.lock()).unwrap().clone(); - let mut path = path.as_path(); - while let Some(parent_path) = path.parent() { - path = parent_path; - if rng.lock().gen() { - break; - } - } + } + 10..=80 if !files.lock().is_empty() => { + let buffer = if self.buffers.is_empty() || rng.lock().gen() { + let file = files.lock().choose(&mut *rng.lock()).unwrap().clone(); + let (worktree, path) = project + .update(&mut cx, |project, cx| { + project.find_or_create_local_worktree(file.clone(), true, cx) + }) + .await + .unwrap(); + let project_path = + worktree.read_with(&cx, |worktree, _| (worktree.id(), path)); + log::info!( + "Host: opening path {:?}, worktree {}, relative_path {:?}", + file, + project_path.0, + project_path.1 + ); + let buffer = project + .update(&mut cx, |project, cx| { + project.open_buffer(project_path, cx) + }) + .await + .unwrap(); + self.buffers.insert(buffer.clone()); + buffer + } else { + self.buffers + .iter() + .choose(&mut *rng.lock()) + .unwrap() + .clone() + }; - log::info!("Host: find/create local worktree {:?}", path); - let find_or_create_worktree = project.update(&mut cx, |project, cx| { - project.find_or_create_local_worktree(path, true, cx) + if rng.lock().gen_bool(0.1) { + cx.update(|cx| { + log::info!( + "Host: dropping buffer {:?}", + buffer.read(cx).file().unwrap().full_path(cx) + ); + self.buffers.remove(&buffer); + drop(buffer); }); - let find_or_create_worktree = async move { - find_or_create_worktree.await.unwrap(); - }; - if rng.lock().gen() { - cx.background().spawn(find_or_create_worktree).detach(); - } else { - find_or_create_worktree.await; - } - } - 10..=80 if !files.lock().is_empty() => { - let buffer = if self.buffers.is_empty() || rng.lock().gen() { - let file = files.lock().choose(&mut *rng.lock()).unwrap().clone(); - let (worktree, path) = project - .update(&mut cx, |project, cx| { - project.find_or_create_local_worktree( - file.clone(), - true, - cx, - ) - }) - .await - .unwrap(); - let project_path = - worktree.read_with(&cx, |worktree, _| (worktree.id(), path)); + } else { + buffer.update(&mut cx, |buffer, cx| { log::info!( - "Host: opening path {:?}, worktree {}, relative_path {:?}", - file, - project_path.0, - project_path.1 + "Host: updating buffer {:?} ({})", + buffer.file().unwrap().full_path(cx), + buffer.remote_id() ); - let buffer = project - .update(&mut cx, |project, cx| { - project.open_buffer(project_path, cx) - }) - .await - .unwrap(); - self.buffers.insert(buffer.clone()); - buffer - } else { - self.buffers - .iter() - .choose(&mut *rng.lock()) - .unwrap() - .clone() - }; - - if rng.lock().gen_bool(0.1) { - cx.update(|cx| { - log::info!( - "Host: dropping buffer {:?}", - buffer.read(cx).file().unwrap().full_path(cx) - ); - self.buffers.remove(&buffer); - drop(buffer); - }); - } else { - buffer.update(&mut cx, |buffer, cx| { - log::info!( - "Host: updating buffer {:?} ({})", - buffer.file().unwrap().full_path(cx), - buffer.remote_id() - ); - buffer.randomly_edit(&mut *rng.lock(), 5, cx) - }); - } + buffer.randomly_edit(&mut *rng.lock(), 5, cx) + }); } - _ => loop { - let path_component_count = rng.lock().gen_range::(1..=5); - let mut path = PathBuf::new(); - path.push("/"); - for _ in 0..path_component_count { - let letter = rng.lock().gen_range(b'a'..=b'z'); - path.push(std::str::from_utf8(&[letter]).unwrap()); - } - path.set_extension("rs"); - let parent_path = path.parent().unwrap(); - - log::info!("Host: creating file {:?}", path,); - - if fs.create_dir(&parent_path).await.is_ok() - && fs.create_file(&path, Default::default()).await.is_ok() - { - files.lock().push(path); - break; - } else { - log::info!("Host: cannot create file"); - } - }, } + _ => loop { + let path_component_count = rng.lock().gen_range::(1..=5); + let mut path = PathBuf::new(); + path.push("/"); + for _ in 0..path_component_count { + let letter = rng.lock().gen_range(b'a'..=b'z'); + path.push(std::str::from_utf8(&[letter]).unwrap()); + } + path.set_extension("rs"); + let parent_path = path.parent().unwrap(); - cx.background().simulate_random_delay().await; - } + log::info!("Host: creating file {:?}", path,); - log::info!("Host done"); + if fs.create_dir(&parent_path).await.is_ok() + && fs.create_file(&path, Default::default()).await.is_ok() + { + files.lock().push(path); + break; + } else { + log::info!("Host: cannot create file"); + } + }, + } - self.project = Some(project); - (self, cx) + cx.background().simulate_random_delay().await; } + + log::info!("Host done"); + + self.project = Some(project); + (self, cx) } pub async fn simulate_guest( From 3b4cab9094152c3bdf101148910aef2c07fae6ab Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 29 Mar 2022 18:11:14 -0700 Subject: [PATCH 09/68] Move all configuration of individual LSP servers to LspAdapter --- crates/language/src/buffer.rs | 3 +- crates/language/src/language.rs | 46 ++++++++++++------- crates/project/src/project.rs | 55 +++++++++++------------ crates/server/src/rpc.rs | 1 + crates/zed/src/languages/rust.rs | 8 ++++ crates/zed/src/languages/rust/config.toml | 4 -- 6 files changed, 65 insertions(+), 52 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 535798083eb6a5de52738e2b85a4829021a3adf9..6cd89aa8bdf0e14606b691127677a8d5be7b6f2a 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1,8 +1,7 @@ pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, - proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, LanguageServerConfig, - PLAIN_TEXT, + proto, BracketPair, Grammar, Language, LanguageConfig, LanguageRegistry, PLAIN_TEXT, }; use crate::{ diagnostic_set::{DiagnosticEntry, DiagnosticGroup}, diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index a98f1a9845c28f4fed6198a270a1f4a20e74b7c1..9c4aee6a301859d5c65fd7c2794090dad860573c 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -8,7 +8,7 @@ mod tests; use anyhow::{anyhow, Context, Result}; use client::http::{self, HttpClient}; -use collections::{HashMap, HashSet}; +use collections::HashMap; use futures::{ future::{BoxFuture, Shared}, FutureExt, TryFutureExt, @@ -52,7 +52,6 @@ lazy_static! { brackets: Default::default(), autoclose_before: Default::default(), line_comment: None, - language_server: Default::default(), }, None, )); @@ -100,6 +99,14 @@ pub trait LspAdapter: 'static + Send + Sync { fn initialization_options(&self) -> Option { None } + + fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] { + Default::default() + } + + fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> { + None + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -117,8 +124,6 @@ pub struct LanguageConfig { #[serde(default)] pub autoclose_before: String, pub line_comment: Option, - #[serde(default)] - pub language_server: LanguageServerConfig, } impl Default for LanguageConfig { @@ -129,22 +134,17 @@ impl Default for LanguageConfig { brackets: Default::default(), autoclose_before: Default::default(), line_comment: Default::default(), - language_server: Default::default(), } } } -#[derive(Default, Deserialize)] -pub struct LanguageServerConfig { - pub disk_based_diagnostic_sources: HashSet, - pub disk_based_diagnostics_progress_token: Option, -} - #[cfg(any(test, feature = "test-support"))] pub struct FakeLspAdapter { pub name: &'static str, pub capabilities: lsp::ServerCapabilities, pub initializer: Option>, + pub disk_based_diagnostics_progress_token: Option<&'static str>, + pub disk_based_diagnostics_sources: &'static [&'static str], } #[derive(Clone, Debug, Deserialize)] @@ -500,15 +500,16 @@ impl Language { self.config.line_comment.as_deref() } - pub fn disk_based_diagnostic_sources(&self) -> &HashSet { - &self.config.language_server.disk_based_diagnostic_sources + pub fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] { + self.adapter.as_ref().map_or(&[] as &[_], |adapter| { + adapter.disk_based_diagnostic_sources() + }) } - pub fn disk_based_diagnostics_progress_token(&self) -> Option<&String> { - self.config - .language_server - .disk_based_diagnostics_progress_token + pub fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> { + self.adapter .as_ref() + .and_then(|adapter| adapter.disk_based_diagnostics_progress_token()) } pub fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams) { @@ -621,10 +622,13 @@ impl Default for FakeLspAdapter { name: "the-fake-language-server", capabilities: lsp::LanguageServer::full_capabilities(), initializer: None, + disk_based_diagnostics_progress_token: None, + disk_based_diagnostics_sources: &[], } } } +#[cfg(any(test, feature = "test-support"))] impl LspAdapter for FakeLspAdapter { fn name(&self) -> LanguageServerName { LanguageServerName(self.name.into()) @@ -651,6 +655,14 @@ impl LspAdapter for FakeLspAdapter { } fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + + fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] { + self.disk_based_diagnostics_sources + } + + fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> { + self.disk_based_diagnostics_progress_token + } } impl ToLspPosition for PointUtf16 { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 1dd0f907f702db274cf580e6f2be829c79fc2e1e..b27edcc8d437750dd71386dc832ef79a9907466a 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1536,7 +1536,7 @@ impl Project { match event { LanguageServerEvent::WorkStart { token } => { - if Some(&token) == disk_diagnostics_token { + if Some(token.as_str()) == disk_diagnostics_token { language_server_status.pending_diagnostic_updates += 1; if language_server_status.pending_diagnostic_updates == 1 { self.disk_based_diagnostics_started(cx); @@ -1558,7 +1558,7 @@ impl Project { } } LanguageServerEvent::WorkProgress { token, progress } => { - if Some(&token) != disk_diagnostics_token { + if Some(token.as_str()) != disk_diagnostics_token { self.on_lsp_work_progress( language_server_id, token.clone(), @@ -1578,7 +1578,7 @@ impl Project { } } LanguageServerEvent::WorkEnd { token } => { - if Some(&token) == disk_diagnostics_token { + if Some(token.as_str()) == disk_diagnostics_token { language_server_status.pending_diagnostic_updates -= 1; if language_server_status.pending_diagnostic_updates == 0 { self.disk_based_diagnostics_finished(cx); @@ -1708,7 +1708,7 @@ impl Project { pub fn update_diagnostics( &mut self, params: lsp::PublishDiagnosticsParams, - disk_based_sources: &HashSet, + disk_based_sources: &[&str], cx: &mut ModelContext, ) -> Result<()> { let abs_path = params @@ -1751,8 +1751,9 @@ impl Project { ); } else { let group_id = post_inc(&mut next_group_id); - let is_disk_based = - source.map_or(false, |source| disk_based_sources.contains(source)); + let is_disk_based = source.map_or(false, |source| { + disk_based_sources.contains(&source.as_str()) + }); sources_by_group_id.insert(group_id, source); primary_diagnostic_group_ids @@ -4606,8 +4607,8 @@ mod tests { use futures::StreamExt; use gpui::test::subscribe; use language::{ - tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, LanguageServerConfig, - OffsetRangeExt, Point, ToPoint, + tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, OffsetRangeExt, Point, + ToPoint, }; use lsp::Url; use serde_json::json; @@ -4906,20 +4907,20 @@ mod tests { async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - let progress_token = "the-progress-token".to_string(); + let progress_token = "the-progress-token"; let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: LanguageServerConfig { - disk_based_diagnostics_progress_token: Some(progress_token.clone()), - ..Default::default() - }, ..Default::default() }, Some(tree_sitter_rust::language()), ); - let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); + let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + disk_based_diagnostics_progress_token: Some(progress_token), + disk_based_diagnostics_sources: &["disk"], + ..Default::default() + }); let fs = FakeFs::new(cx.background()); fs.insert_tree( @@ -4956,15 +4957,15 @@ mod tests { let mut events = subscribe(&project, cx); let mut fake_server = fake_servers.next().await.unwrap(); - fake_server.start_progress(&progress_token).await; + fake_server.start_progress(progress_token).await; assert_eq!( events.next().await.unwrap(), Event::DiskBasedDiagnosticsStarted ); - fake_server.start_progress(&progress_token).await; - fake_server.end_progress(&progress_token).await; - fake_server.start_progress(&progress_token).await; + fake_server.start_progress(progress_token).await; + fake_server.end_progress(progress_token).await; + fake_server.start_progress(progress_token).await; fake_server.notify::( lsp::PublishDiagnosticsParams { @@ -4983,8 +4984,8 @@ mod tests { Event::DiagnosticsUpdated((worktree_id, Path::new("a.rs")).into()) ); - fake_server.end_progress(&progress_token).await; - fake_server.end_progress(&progress_token).await; + fake_server.end_progress(progress_token).await; + fake_server.end_progress(progress_token).await; assert_eq!( events.next().await.unwrap(), Event::DiskBasedDiagnosticsUpdated @@ -5024,20 +5025,18 @@ mod tests { async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) { cx.foreground().forbid_parking(); - // let (mut lsp_config, mut fake_servers) = LanguageServerConfig::fake(); let mut language = Language::new( LanguageConfig { name: "Rust".into(), path_suffixes: vec!["rs".to_string()], - language_server: LanguageServerConfig { - disk_based_diagnostic_sources: ["disk".to_string()].into_iter().collect(), - ..Default::default() - }, ..Default::default() }, Some(tree_sitter_rust::language()), ); - let mut fake_servers = language.set_fake_lsp_adapter(Default::default()); + let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter { + disk_based_diagnostics_sources: &["disk"], + ..Default::default() + }); let text = " fn a() { A } @@ -6551,9 +6550,7 @@ mod tests { }; project - .update(cx, |p, cx| { - p.update_diagnostics(message, &Default::default(), cx) - }) + .update(cx, |p, cx| p.update_diagnostics(message, &[], cx)) .unwrap(); let buffer = buffer.read_with(cx, |buffer, _| buffer.snapshot()); diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 0f8720c673b731e1f75c63650f46ea0ac7f1aa33..1b22d09b567214ec0311e6ae23e75ca0cff86d92 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -5001,6 +5001,7 @@ mod tests { }); } })), + ..Default::default() }); host_language_registry.add(Arc::new(language)); diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 4034e5effa32b216cfcd22dc3f91c5aa1ce3cb69..4f738180420135ff618ba1144efb9769eeae28c6 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -112,6 +112,14 @@ impl LspAdapter for RustLspAdapter { .boxed() } + fn disk_based_diagnostic_sources(&self) -> &'static [&'static str] { + &["rustc"] + } + + fn disk_based_diagnostics_progress_token(&self) -> Option<&'static str> { + Some("rustAnalyzer/cargo check") + } + fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) { lazy_static! { static ref REGEX: Regex = Regex::new("(?m)`([^`]+)\n`$").unwrap(); diff --git a/crates/zed/src/languages/rust/config.toml b/crates/zed/src/languages/rust/config.toml index 97fe231e0fa2bd2cb457c295659b9da10b8c656c..e4d222cddedaa5a004b71a74ed7d3d4dd9608bb2 100644 --- a/crates/zed/src/languages/rust/config.toml +++ b/crates/zed/src/languages/rust/config.toml @@ -10,7 +10,3 @@ brackets = [ { start = "\"", end = "\"", close = true, newline = false }, { start = "/*", end = " */", close = true, newline = false }, ] - -[language_server] -disk_based_diagnostic_sources = ["rustc"] -disk_based_diagnostics_progress_token = "rustAnalyzer/cargo check" From 45ad5f343f0e501283669493e618c3d732ba88ef Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 29 Mar 2022 18:14:42 -0700 Subject: [PATCH 10/68] Parse JS as TSX --- crates/zed/src/languages/tsx/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/zed/src/languages/tsx/config.toml b/crates/zed/src/languages/tsx/config.toml index 62717266df9e0bd56d83b336cfbf28aa2b01ee4b..a6f4a6d2d000d5bcf83219a27b52446178c7e079 100644 --- a/crates/zed/src/languages/tsx/config.toml +++ b/crates/zed/src/languages/tsx/config.toml @@ -1,5 +1,5 @@ name = "TSX" -path_suffixes = ["tsx"] +path_suffixes = ["tsx", "js"] line_comment = "// " autoclose_before = ";:.,=}])>" brackets = [ From cf9efd70057c129495dc3184b1056ba6aff3fdcc Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 30 Mar 2022 16:48:57 -0700 Subject: [PATCH 11/68] Improve installation of npm-based language servers * Use --prefix flag to guarantee that they are installed in .zed * Use the @latest tag when available * Extract helper functions Co-authored-by: Keith Simmons --- crates/language/src/language.rs | 7 +- crates/zed/src/languages.rs | 15 +-- crates/zed/src/languages/c.rs | 37 ++------ crates/zed/src/languages/installation.rs | 111 +++++++++++++++++++++++ crates/zed/src/languages/rust.rs | 37 ++------ crates/zed/src/languages/typescript.rs | 59 +++--------- 6 files changed, 141 insertions(+), 125 deletions(-) create mode 100644 crates/zed/src/languages/installation.rs diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index fb736736b6ecd338c7de24133cee682c7c65731b..66cafb422b83c8fd969c0b92a90e1dbd7470804b 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -7,7 +7,7 @@ pub mod proto; mod tests; use anyhow::{anyhow, Context, Result}; -use client::http::{self, HttpClient}; +use client::http::HttpClient; use collections::HashMap; use futures::{ future::{BoxFuture, Shared}, @@ -61,11 +61,6 @@ pub trait ToLspPosition { fn to_lsp_position(self) -> lsp::Position; } -pub struct GitHubLspBinaryVersion { - pub name: String, - pub url: http::Url, -} - #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct LanguageServerName(pub Arc); diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index cc22247025a393cb104ee4317bc76a47155988d3..75a5030ec6a9991ef87d7ebc764c5aabaa6d27d6 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -1,11 +1,10 @@ -use client::http; use gpui::Task; pub use language::*; use rust_embed::RustEmbed; -use serde::Deserialize; use std::{borrow::Cow, str, sync::Arc}; mod c; +mod installation; mod json; mod rust; mod typescript; @@ -15,18 +14,6 @@ mod typescript; #[exclude = "*.rs"] struct LanguageDir; -#[derive(Deserialize)] -struct GithubRelease { - name: String, - assets: Vec, -} - -#[derive(Deserialize)] -struct GithubReleaseAsset { - name: String, - browser_download_url: http::Url, -} - pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegistry { let languages = LanguageRegistry::new(login_shell_env_loaded); for (name, grammar, lsp_adapter) in [ diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index 56994db4251d995d347cb248279e52e3272d84d5..f2ce41a2378cd27c20e8134900ab862eed0fa0b5 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -1,13 +1,12 @@ +use super::installation::{latest_github_release, GitHubLspBinaryVersion}; use anyhow::{anyhow, Result}; -use client::http::{self, HttpClient, Method}; +use client::http::{HttpClient, Method}; use futures::{future::BoxFuture, FutureExt, StreamExt}; pub use language::*; use smol::fs::{self, File}; use std::{any::Any, path::PathBuf, sync::Arc}; use util::{ResultExt, TryFutureExt}; -use super::GithubRelease; - pub struct CLspAdapter; impl super::LspAdapter for CLspAdapter { @@ -20,33 +19,11 @@ impl super::LspAdapter for CLspAdapter { http: Arc, ) -> BoxFuture<'static, Result>> { async move { - let release = http - .send( - surf::RequestBuilder::new( - Method::Get, - http::Url::parse( - "https://api.github.com/repos/clangd/clangd/releases/latest", - ) - .unwrap(), - ) - .middleware(surf::middleware::Redirect::default()) - .build(), - ) - .await - .map_err(|err| anyhow!("error fetching latest release: {}", err))? - .body_json::() - .await - .map_err(|err| anyhow!("error parsing latest release: {}", err))?; - let asset_name = format!("clangd-mac-{}.zip", release.name); - let asset = release - .assets - .iter() - .find(|asset| asset.name == asset_name) - .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; - Ok(Box::new(GitHubLspBinaryVersion { - name: release.name, - url: asset.browser_download_url.clone(), - }) as Box<_>) + let version = latest_github_release("clangd/clangd", http, |release_name| { + format!("clangd-mac-{release_name}.zip") + }) + .await?; + Ok(Box::new(version) as Box<_>) } .boxed() } diff --git a/crates/zed/src/languages/installation.rs b/crates/zed/src/languages/installation.rs new file mode 100644 index 0000000000000000000000000000000000000000..212ff472fcc224c6586ebc7e59cf450e49230f8c --- /dev/null +++ b/crates/zed/src/languages/installation.rs @@ -0,0 +1,111 @@ +use anyhow::{anyhow, Context, Result}; +use client::http::{self, HttpClient, Method}; +use serde::Deserialize; +use std::{path::Path, sync::Arc}; + +pub struct GitHubLspBinaryVersion { + pub name: String, + pub url: http::Url, +} + +#[derive(Deserialize)] +#[serde(rename_all = "kebab-case")] +struct NpmInfo { + #[serde(default)] + dist_tags: NpmInfoDistTags, + versions: Vec, +} + +#[derive(Deserialize, Default)] +struct NpmInfoDistTags { + latest: Option, +} + +#[derive(Deserialize)] +pub(crate) struct GithubRelease { + name: String, + assets: Vec, +} + +#[derive(Deserialize)] +pub(crate) struct GithubReleaseAsset { + name: String, + browser_download_url: http::Url, +} + +pub async fn npm_package_latest_version(name: &str) -> Result { + let output = smol::process::Command::new("npm") + .args(["info", name, "--json"]) + .output() + .await?; + if !output.status.success() { + Err(anyhow!( + "failed to execute npm info: {:?}", + String::from_utf8_lossy(&output.stderr) + ))?; + } + let mut info: NpmInfo = serde_json::from_slice(&output.stdout)?; + info.dist_tags + .latest + .or_else(|| info.versions.pop()) + .ok_or_else(|| anyhow!("no version found for npm package {}", name)) +} + +pub async fn npm_install_packages( + packages: impl IntoIterator, + directory: &Path, +) -> Result<()> { + let output = smol::process::Command::new("npm") + .arg("install") + .arg("--prefix") + .arg(directory) + .args( + packages + .into_iter() + .map(|(name, version)| format!("{name}@{version}")), + ) + .output() + .await + .context("failed to run npm install")?; + if !output.status.success() { + Err(anyhow!( + "failed to execute npm install: {:?}", + String::from_utf8_lossy(&output.stderr) + ))?; + } + Ok(()) +} + +pub async fn latest_github_release( + repo_name_with_owner: &str, + http: Arc, + asset_name: impl Fn(&str) -> String, +) -> Result { + let release = http + .send( + surf::RequestBuilder::new( + Method::Get, + http::Url::parse(&format!( + "https://api.github.com/repos/{repo_name_with_owner}/releases/latest" + )) + .unwrap(), + ) + .middleware(surf::middleware::Redirect::default()) + .build(), + ) + .await + .map_err(|err| anyhow!("error fetching latest release: {}", err))? + .body_json::() + .await + .map_err(|err| anyhow!("error parsing latest release: {}", err))?; + let asset_name = asset_name(&release.name); + let asset = release + .assets + .iter() + .find(|asset| asset.name == asset_name) + .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?; + Ok(GitHubLspBinaryVersion { + name: release.name, + url: asset.browser_download_url.clone(), + }) +} diff --git a/crates/zed/src/languages/rust.rs b/crates/zed/src/languages/rust.rs index 4f738180420135ff618ba1144efb9769eeae28c6..f419f59abb4bdc89e2202e84879988ade69ba045 100644 --- a/crates/zed/src/languages/rust.rs +++ b/crates/zed/src/languages/rust.rs @@ -1,6 +1,7 @@ +use super::installation::{latest_github_release, GitHubLspBinaryVersion}; use anyhow::{anyhow, Result}; use async_compression::futures::bufread::GzipDecoder; -use client::http::{self, HttpClient, Method}; +use client::http::{HttpClient, Method}; use futures::{future::BoxFuture, FutureExt, StreamExt}; pub use language::*; use lazy_static::lazy_static; @@ -9,8 +10,6 @@ use smol::fs::{self, File}; use std::{any::Any, borrow::Cow, env::consts, path::PathBuf, str, sync::Arc}; use util::{ResultExt, TryFutureExt}; -use super::GithubRelease; - pub struct RustLspAdapter; impl LspAdapter for RustLspAdapter { @@ -23,33 +22,11 @@ impl LspAdapter for RustLspAdapter { http: Arc, ) -> BoxFuture<'static, Result>> { async move { - let release = http - .send( - surf::RequestBuilder::new( - Method::Get, - http::Url::parse( - "https://api.github.com/repos/rust-analyzer/rust-analyzer/releases/latest", - ) - .unwrap(), - ) - .middleware(surf::middleware::Redirect::default()) - .build(), - ) - .await - .map_err(|err| anyhow!("error fetching latest release: {}", err))? - .body_json::() - .await - .map_err(|err| anyhow!("error parsing latest release: {}", err))?; - let asset_name = format!("rust-analyzer-{}-apple-darwin.gz", consts::ARCH); - let asset = release - .assets - .iter() - .find(|asset| asset.name == asset_name) - .ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?; - Ok(Box::new(GitHubLspBinaryVersion { - name: release.name, - url: asset.browser_download_url.clone(), - }) as Box<_>) + let version = latest_github_release("rust-analyzer/rust-analyzer", http, |_| { + format!("rust-analyzer-{}-apple-darwin.gz", consts::ARCH) + }) + .await?; + Ok(Box::new(version) as Box<_>) } .boxed() } diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 4d7af34c38cf2c35ed030136c3f75395efeb9d2a..d08da116a544478693ceeea3a397868b653613cd 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -1,8 +1,8 @@ +use super::installation::{npm_install_packages, npm_package_latest_version}; use anyhow::{anyhow, Context, Result}; use client::http::HttpClient; use futures::{future::BoxFuture, FutureExt, StreamExt}; use language::{LanguageServerName, LspAdapter}; -use serde::Deserialize; use serde_json::json; use smol::fs; use std::{any::Any, path::PathBuf, sync::Arc}; @@ -33,37 +33,9 @@ impl LspAdapter for TypeScriptLspAdapter { _: Arc, ) -> BoxFuture<'static, Result>> { async move { - #[derive(Deserialize)] - struct NpmInfo { - versions: Vec, - } - - let typescript_output = smol::process::Command::new("npm") - .args(["info", "typescript", "--json"]) - .output() - .await?; - if !typescript_output.status.success() { - Err(anyhow!("failed to execute npm info"))?; - } - let mut typescript_info: NpmInfo = serde_json::from_slice(&typescript_output.stdout)?; - - let server_output = smol::process::Command::new("npm") - .args(["info", "typescript-language-server", "--json"]) - .output() - .await?; - if !server_output.status.success() { - Err(anyhow!("failed to execute npm info"))?; - } - let mut server_info: NpmInfo = serde_json::from_slice(&server_output.stdout)?; - Ok(Box::new(Versions { - typescript_version: typescript_info - .versions - .pop() - .ok_or_else(|| anyhow!("no versions found in typescript npm info"))?, - server_version: server_info.versions.pop().ok_or_else(|| { - anyhow!("no versions found in typescript language server npm info") - })?, + typescript_version: npm_package_latest_version("typescript").await?, + server_version: npm_package_latest_version("typescript-language-server").await?, }) as Box<_>) } .boxed() @@ -87,20 +59,17 @@ impl LspAdapter for TypeScriptLspAdapter { let binary_path = version_dir.join(Self::BIN_PATH); if fs::metadata(&binary_path).await.is_err() { - let output = smol::process::Command::new("npm") - .current_dir(&version_dir) - .arg("install") - .arg(format!("typescript@{}", versions.typescript_version)) - .arg(format!( - "typescript-language-server@{}", - versions.server_version - )) - .output() - .await - .context("failed to run npm install")?; - if !output.status.success() { - Err(anyhow!("failed to install typescript-language-server"))?; - } + npm_install_packages( + [ + ("typescript", versions.typescript_version.as_str()), + ( + "typescript-language-server", + &versions.server_version.as_str(), + ), + ], + &version_dir, + ) + .await?; if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() { while let Some(entry) = entries.next().await { From c280c85ce714575f1fd7ee980a75211a9ce3c993 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 30 Mar 2022 17:08:40 -0700 Subject: [PATCH 12/68] Hard-code LSP formatting options for now This is needed for auto-formatting to work properly in TypeScript and JSON Co-Authored-By: Keith Simmons --- crates/lsp/src/lsp.rs | 2 ++ crates/project/src/project.rs | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index de47381c4666b7980b1c484d06fdae770d032767..51a68b83c8997747ffe0880fdab7f9d597417008 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -181,6 +181,7 @@ impl LanguageServer { buffer.resize(message_len, 0); stdout.read_exact(&mut buffer).await?; + log::trace!("incoming message:{}", String::from_utf8_lossy(&buffer)); if let Ok(AnyNotification { id, method, params }) = serde_json::from_slice(&buffer) @@ -229,6 +230,7 @@ impl LanguageServer { let _clear_response_handlers = ClearResponseHandlers(response_handlers); let mut content_len_buffer = Vec::new(); while let Ok(message) = outbound_rx.recv().await { + log::trace!("outgoing message:{}", String::from_utf8_lossy(&message)); content_len_buffer.clear(); write!(content_len_buffer, "{}", message.len()).unwrap(); stdin.write_all(CONTENT_LEN_HEADER.as_bytes()).await?; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 5a415ca3eb320a63c838300457faf47f3c494179..e859e756f86d0c7abde09392d504abc17a828625 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2046,7 +2046,12 @@ impl Project { language_server .request::(lsp::DocumentFormattingParams { text_document, - options: Default::default(), + options: lsp::FormattingOptions { + tab_size: 4, + insert_spaces: true, + insert_final_newline: Some(true), + ..Default::default() + }, work_done_progress_params: Default::default(), }) .await? @@ -2064,7 +2069,12 @@ impl Project { lsp::DocumentRangeFormattingParams { text_document, range: lsp::Range::new(buffer_start, buffer_end), - options: Default::default(), + options: lsp::FormattingOptions { + tab_size: 4, + insert_spaces: true, + insert_final_newline: Some(true), + ..Default::default() + }, work_done_progress_params: Default::default(), }, ) From 263e3d817667211375686ae8853348017f0657ae Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 30 Mar 2022 17:47:25 -0700 Subject: [PATCH 13/68] Start work on interpreting 'label/insertText' completions These completions don't supply a range that should be overwritten, so the client needs to infer it via substring matching. Co-authored-by: Keith Simmons --- crates/project/src/project.rs | 5 ++++- crates/text/src/tests.rs | 9 +++++++++ crates/text/src/text.rs | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e859e756f86d0c7abde09392d504abc17a828625..77dfc741c159d5871f15da33f8bb2ed1f53514bf 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2363,7 +2363,10 @@ impl Project { Some(lsp::CompletionTextEdit::Edit(edit)) => { (range_from_lsp(edit.range), edit.new_text.clone()) } - None => (position..position, lsp_completion.label.clone()), + None => ( + this.common_prefix_at_position(position, &lsp_completion.label), + lsp_completion.label.clone(), + ), Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { log::info!("unsupported insert/replace completion"); return None; diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs index 7961dccd569c8380c3bb32e57e9057481e4371fd..0faf8e19de91e8b6c9b2416d6874cda55d458f30 100644 --- a/crates/text/src/tests.rs +++ b/crates/text/src/tests.rs @@ -164,6 +164,15 @@ fn test_line_len() { assert_eq!(buffer.line_len(5), 0); } +#[test] +fn test_common_prefix_at_positionn() { + let buffer = Buffer::new(0, 0, History::new("a = (bcd)".into())); + assert_eq!( + buffer.common_prefix_at_position(Point::new(0, 8), "bcdef"), + Point::new(0, 5)..Point::new(0, 8) + ) +} + #[test] fn test_text_summary_for_range() { let buffer = Buffer::new(0, 0, History::new("ab\nefg\nhklm\nnopqrs\ntuvwxyz".into())); diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index b811d08c046c58f8c5d6c020c27c45a430258474..0e742f8a8b74517058adfe2ba448a3be1a85ca37 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1508,6 +1508,13 @@ impl BufferSnapshot { .eq(needle.bytes()) } + pub fn common_prefix_at_position(&self, position: T, needle: &str) -> Range + where + T: TextDimension + ToOffset, + { + todo!() + } + pub fn text(&self) -> String { self.visible_text.to_string() } From 9385690b988cacfadf28e55ecbcc799170ca8131 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 00:55:55 -0700 Subject: [PATCH 14/68] Add test for common_prefix_at and rewrite it to be more readable and pass the new test cases --- crates/project/src/project.rs | 2 +- crates/text/src/tests.rs | 10 +++++++--- crates/text/src/text.rs | 29 ++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 77dfc741c159d5871f15da33f8bb2ed1f53514bf..df84aec0c5f13219ace51c1e5d8d08b325e8db1c 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2364,7 +2364,7 @@ impl Project { (range_from_lsp(edit.range), edit.new_text.clone()) } None => ( - this.common_prefix_at_position(position, &lsp_completion.label), + this.common_prefix_at(position, &lsp_completion.label), lsp_completion.label.clone(), ), Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs index 0faf8e19de91e8b6c9b2416d6874cda55d458f30..54e802b52194721484761e95507de9af516b0512 100644 --- a/crates/text/src/tests.rs +++ b/crates/text/src/tests.rs @@ -7,6 +7,7 @@ use std::{ iter::Iterator, time::{Duration, Instant}, }; +use util::test::marked_text_ranges; #[cfg(test)] #[ctor::ctor] @@ -166,10 +167,13 @@ fn test_line_len() { #[test] fn test_common_prefix_at_positionn() { - let buffer = Buffer::new(0, 0, History::new("a = (bcd)".into())); + let (text, ranges) = marked_text_ranges("a = [bcd]"); + let buffer = Buffer::new(0, 0, History::new(text.into())); + let snapshot = &buffer.snapshot(); + let expected_range = ranges[0].to_offset(&snapshot); assert_eq!( - buffer.common_prefix_at_position(Point::new(0, 8), "bcdef"), - Point::new(0, 5)..Point::new(0, 8) + buffer.common_prefix_at(expected_range.end, "bcdef"), + expected_range ) } diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 0e742f8a8b74517058adfe2ba448a3be1a85ca37..ea0af9d21f5394409dbeda9d5d22f4964110ebf5 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1508,11 +1508,34 @@ impl BufferSnapshot { .eq(needle.bytes()) } - pub fn common_prefix_at_position(&self, position: T, needle: &str) -> Range + pub fn common_prefix_at(&self, position: T, needle: &str) -> Range where - T: TextDimension + ToOffset, + T: Clone + ToOffset + FromAnchor, { - todo!() + let position_offset = position.to_offset(self); + // Get byte indices and char counts for every character in needle in reverse order + let char_indices = needle + .char_indices() + .map(|(index, _)| index) + .chain(std::iter::once(needle.len())) + .enumerate() + // Don't test any prefixes that are bigger than the requested position + .take_while(|(_, prefix_length)| *prefix_length <= position_offset); + + let start = char_indices + // Compute the prefix string and prefix start location + .map(move |(byte_position, char_length)| { + (position_offset - char_length, &needle[..byte_position]) + }) + // Only take strings when the prefix is contained at the expected prefix position + .filter(|(prefix_offset, prefix)| self.contains_str_at(prefix_offset, prefix)) + // Convert offset to T + .map(|(prefix_offset, _)| T::from_anchor(&self.anchor_before(prefix_offset), self)) + .last() + // If no prefix matches, return the passed in position to create an empty range + .unwrap_or(position.clone()); + + start..position } pub fn text(&self) -> String { From 564225c4015340bdd87bfae551b690ea16904119 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 15:39:52 -0700 Subject: [PATCH 15/68] Provide diagnostic context to codeAction Co-authored-by: Max Brunsfeld --- crates/language/src/diagnostic_set.rs | 17 +++++++++++ crates/language/src/language.rs | 17 ++++++----- crates/project/src/lsp_command.rs | 14 ++++----- crates/project/src/project.rs | 41 +++++++++++++-------------- crates/server/src/rpc.rs | 13 +++------ 5 files changed, 58 insertions(+), 44 deletions(-) diff --git a/crates/language/src/diagnostic_set.rs b/crates/language/src/diagnostic_set.rs index 490789a8c80c3abe320d54bc12b88ec3529832cc..51c921e61c90081e516376ad25d729315d13c678 100644 --- a/crates/language/src/diagnostic_set.rs +++ b/crates/language/src/diagnostic_set.rs @@ -34,6 +34,23 @@ pub struct Summary { count: usize, } +impl DiagnosticEntry { + // Used to provide diagnostic context to lsp codeAction request + pub fn to_lsp_diagnostic_stub(&self) -> lsp::Diagnostic { + let code = self + .diagnostic + .code + .clone() + .map(lsp::NumberOrString::String); + + lsp::Diagnostic { + code, + severity: Some(self.diagnostic.severity), + ..Default::default() + } + } +} + impl DiagnosticSet { pub fn from_sorted_entries(iter: I, buffer: &text::BufferSnapshot) -> Self where diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 66cafb422b83c8fd969c0b92a90e1dbd7470804b..243597320190782c2cbdaaf5ccf9ce4ba9c2407e 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -662,18 +662,21 @@ impl LspAdapter for FakeLspAdapter { } } -impl ToLspPosition for PointUtf16 { - fn to_lsp_position(self) -> lsp::Position { - lsp::Position::new(self.row, self.column) - } +pub fn point_to_lsp(point: PointUtf16) -> lsp::Position { + lsp::Position::new(point.row, point.column) } pub fn point_from_lsp(point: lsp::Position) -> PointUtf16 { PointUtf16::new(point.line, point.character) } +pub fn range_to_lsp(range: Range) -> lsp::Range { + lsp::Range { + start: point_to_lsp(range.start), + end: point_to_lsp(range.end), + } +} + pub fn range_from_lsp(range: lsp::Range) -> Range { - let start = PointUtf16::new(range.start.line, range.start.character); - let end = PointUtf16::new(range.end.line, range.end.character); - start..end + point_from_lsp(range.start)..point_from_lsp(range.end) } diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index b6f007659dad840b3ee9145131fd522498f5524d..71ad489d07320af8a3e45ece6e7df6d4b163f551 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -4,9 +4,9 @@ use async_trait::async_trait; use client::{proto, PeerId}; use gpui::{AppContext, AsyncAppContext, ModelHandle}; use language::{ - point_from_lsp, + point_from_lsp, point_to_lsp, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, - range_from_lsp, Anchor, Bias, Buffer, PointUtf16, ToLspPosition, ToPointUtf16, + range_from_lsp, Anchor, Bias, Buffer, PointUtf16, ToPointUtf16, }; use lsp::{DocumentHighlightKind, ServerCapabilities}; use std::{cmp::Reverse, ops::Range, path::Path}; @@ -91,7 +91,7 @@ impl LspCommand for PrepareRename { text_document: lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(path).unwrap(), }, - position: self.position.to_lsp_position(), + position: point_to_lsp(self.position), } } @@ -208,7 +208,7 @@ impl LspCommand for PerformRename { text_document: lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(path).unwrap(), }, - position: self.position.to_lsp_position(), + position: point_to_lsp(self.position), }, new_name: self.new_name.clone(), work_done_progress_params: Default::default(), @@ -325,7 +325,7 @@ impl LspCommand for GetDefinition { text_document: lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(path).unwrap(), }, - position: self.position.to_lsp_position(), + position: point_to_lsp(self.position), }, work_done_progress_params: Default::default(), partial_result_params: Default::default(), @@ -497,7 +497,7 @@ impl LspCommand for GetReferences { text_document: lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(path).unwrap(), }, - position: self.position.to_lsp_position(), + position: point_to_lsp(self.position), }, work_done_progress_params: Default::default(), partial_result_params: Default::default(), @@ -659,7 +659,7 @@ impl LspCommand for GetDocumentHighlights { text_document: lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(path).unwrap(), }, - position: self.position.to_lsp_position(), + position: point_to_lsp(self.position), }, work_done_progress_params: Default::default(), partial_result_params: Default::default(), diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index df84aec0c5f13219ace51c1e5d8d08b325e8db1c..65c943c888247b5c02badc3e3b59c603f325a290 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -15,11 +15,12 @@ use gpui::{ MutableAppContext, Task, UpgradeModelHandle, WeakModelHandle, }; use language::{ + point_to_lsp, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, - range_from_lsp, Anchor, Bias, Buffer, CodeAction, CodeLabel, Completion, Diagnostic, - DiagnosticEntry, DiagnosticSet, Event as BufferEvent, File as _, Language, LanguageRegistry, - LanguageServerName, LocalFile, LspAdapter, OffsetRangeExt, Operation, Patch, PointUtf16, - TextBufferSnapshot, ToLspPosition, ToOffset, ToPointUtf16, Transaction, + range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CodeAction, CodeLabel, Completion, + Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, File as _, Language, + LanguageRegistry, LanguageServerName, LocalFile, LspAdapter, OffsetRangeExt, Operation, Patch, + PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, }; use lsp::{DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer}; use lsp_command::*; @@ -1215,8 +1216,8 @@ impl Project { .collect(); lsp::TextDocumentContentChangeEvent { range: Some(lsp::Range::new( - edit_start.to_lsp_position(), - edit_end.to_lsp_position(), + point_to_lsp(edit_start), + point_to_lsp(edit_end), )), range_length: None, text: new_text, @@ -2061,9 +2062,8 @@ impl Project { .map_or(false, |provider| *provider != lsp::OneOf::Left(false)) { let buffer_start = lsp::Position::new(0, 0); - let buffer_end = buffer - .read_with(&cx, |buffer, _| buffer.max_point_utf16()) - .to_lsp_position(); + let buffer_end = + buffer.read_with(&cx, |buffer, _| point_to_lsp(buffer.max_point_utf16())); language_server .request::( lsp::DocumentRangeFormattingParams { @@ -2337,7 +2337,7 @@ impl Project { lsp::TextDocumentIdentifier::new( lsp::Url::from_file_path(buffer_abs_path).unwrap(), ), - position.to_lsp_position(), + point_to_lsp(position), ), context: Default::default(), work_done_progress_params: Default::default(), @@ -2511,7 +2511,7 @@ impl Project { } } - pub fn code_actions( + pub fn code_actions( &self, buffer_handle: &ModelHandle, range: Range, @@ -2519,6 +2519,11 @@ impl Project { ) -> Task>> { let buffer_handle = buffer_handle.clone(); let buffer = buffer_handle.read(cx); + let snapshot = buffer.snapshot(); + let relevant_diagnostics = snapshot + .diagnostics_in_range::(range.to_offset(&snapshot), false) + .map(|entry| entry.to_lsp_diagnostic_stub()) + .collect(); let buffer_id = buffer.remote_id(); let worktree; let buffer_abs_path; @@ -2539,10 +2544,7 @@ impl Project { return Task::ready(Ok(Default::default())); }; - let lsp_range = lsp::Range::new( - range.start.to_point_utf16(buffer).to_lsp_position(), - range.end.to_point_utf16(buffer).to_lsp_position(), - ); + let lsp_range = range_to_lsp(range.to_point_utf16(buffer)); cx.foreground().spawn(async move { if !lang_server.capabilities().code_action_provider.is_some() { return Ok(Default::default()); @@ -2557,11 +2559,12 @@ impl Project { work_done_progress_params: Default::default(), partial_result_params: Default::default(), context: lsp::CodeActionContext { - diagnostics: Default::default(), + diagnostics: relevant_diagnostics, only: Some(vec![ lsp::CodeActionKind::QUICKFIX, lsp::CodeActionKind::REFACTOR, lsp::CodeActionKind::REFACTOR_EXTRACT, + lsp::CodeActionKind::SOURCE, ]), }, }) @@ -2636,11 +2639,7 @@ impl Project { .and_then(|d| d.get_mut("codeActionParams")) .and_then(|d| d.get_mut("range")) { - *lsp_range = serde_json::to_value(&lsp::Range::new( - range.start.to_lsp_position(), - range.end.to_lsp_position(), - )) - .unwrap(); + *lsp_range = serde_json::to_value(&range_to_lsp(range)).unwrap(); action.lsp_action = lang_server .request::(action.lsp_action) .await?; diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 1b22d09b567214ec0311e6ae23e75ca0cff86d92..a010e55c32940e8f1ec5304e87d0798557b72f74 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -1088,8 +1088,8 @@ mod tests { }; use gpui::{executor, geometry::vector::vec2f, ModelHandle, TestAppContext, ViewHandle}; use language::{ - tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, LanguageConfig, - LanguageRegistry, OffsetRangeExt, Point, ToLspPosition, + range_to_lsp, tree_sitter_rust, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, + LanguageConfig, LanguageRegistry, OffsetRangeExt, Point, }; use lsp::{self, FakeLanguageServer}; use parking_lot::Mutex; @@ -4979,14 +4979,9 @@ mod tests { for _ in 0..highlight_count { let range = buffer.random_byte_range(prev_end, &mut *rng.lock()); - let start = buffer - .offset_to_point_utf16(range.start) - .to_lsp_position(); - let end = buffer - .offset_to_point_utf16(range.end) - .to_lsp_position(); + highlights.push(lsp::DocumentHighlight { - range: lsp::Range::new(start, end), + range: range_to_lsp(range.to_point_utf16(buffer)), kind: Some(lsp::DocumentHighlightKind::READ), }); prev_end = range.end; From afbddc1bcde8543dee73a818c4a660e3116a7efe Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 18:22:55 -0700 Subject: [PATCH 16/68] Address panic when completions requested and returned to outdated buffer --- crates/project/src/project.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 65c943c888247b5c02badc3e3b59c603f325a290..856405d620a0e00741b8e7976d4e560db6e3d6c5 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2331,6 +2331,13 @@ impl Project { }; cx.spawn(|_, cx| async move { + let clipped_position = source_buffer_handle + .read_with(&cx, |this, _| this.clip_point_utf16(position, Bias::Left)); + if clipped_position != position { + log::info!("Completion position out of date"); + return Ok(Default::default()); + } + let completions = lang_server .request::(lsp::CompletionParams { text_document_position: lsp::TextDocumentPositionParams::new( From e987a8ba634dbd5246ec1d4dc4f7ab3f61e4f8b8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 31 Mar 2022 21:52:14 -0700 Subject: [PATCH 17/68] Let fake and real LanguageServer access AsyncAppContext in handler callbacks Also, reimplement FakeLanguageServer by wrapping LanguageServer, instead of duplicating its functionality differently. --- crates/editor/src/editor.rs | 14 +- crates/language/src/language.rs | 18 +- crates/lsp/src/lsp.rs | 496 +++++++++++++------------------- crates/project/src/project.rs | 82 +++--- crates/server/src/rpc.rs | 118 ++++---- 5 files changed, 313 insertions(+), 415 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c7373d84f27863fe5f9d03702cf438d5c14fc280..0dccce37a9e5461c113f79b89f3faa2cdcd04d8f 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8928,7 +8928,7 @@ mod tests { .unwrap(); cx.foreground().start_waiting(); - let mut fake_server = fake_servers.next().await.unwrap(); + let fake_server = fake_servers.next().await.unwrap(); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); @@ -8942,10 +8942,10 @@ mod tests { params.text_document.uri, lsp::Url::from_file_path("/file.rs").unwrap() ); - Some(vec![lsp::TextEdit::new( + Ok(Some(vec![lsp::TextEdit::new( lsp::Range::new(lsp::Position::new(0, 3), lsp::Position::new(1, 0)), ", ".to_string(), - )]) + )])) }) .next() .await; @@ -9173,7 +9173,7 @@ mod tests { params.text_document_position.position, lsp::Position::new(position.row, position.column) ); - Some(lsp::CompletionResponse::Array( + Ok(Some(lsp::CompletionResponse::Array( completions .iter() .map(|(range, new_text)| lsp::CompletionItem { @@ -9188,7 +9188,7 @@ mod tests { ..Default::default() }) .collect(), - )) + ))) } }) .next() @@ -9202,7 +9202,7 @@ mod tests { fake.handle_request::(move |_, _| { let edit = edit.clone(); async move { - lsp::CompletionItem { + Ok(lsp::CompletionItem { additional_text_edits: edit.map(|(range, new_text)| { vec![lsp::TextEdit::new( lsp::Range::new( @@ -9213,7 +9213,7 @@ mod tests { )] }), ..Default::default() - } + }) } }) .next() diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 243597320190782c2cbdaaf5ccf9ce4ba9c2407e..322fd19b9e8de659202ff2773907932109917bdc 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -263,14 +263,12 @@ impl LanguageRegistry { #[cfg(any(test, feature = "test-support"))] if language.fake_adapter.is_some() { let language = language.clone(); - return Some(cx.spawn(|mut cx| async move { + return Some(cx.spawn(|cx| async move { let (servers_tx, fake_adapter) = language.fake_adapter.as_ref().unwrap(); - let (server, mut fake_server) = cx.update(|cx| { - lsp::LanguageServer::fake_with_capabilities( - fake_adapter.capabilities.clone(), - cx, - ) - }); + let (server, mut fake_server) = lsp::LanguageServer::fake_with_capabilities( + fake_adapter.capabilities.clone(), + cx.clone(), + ); if let Some(initializer) = &fake_adapter.initializer { initializer(&mut fake_server); @@ -297,10 +295,9 @@ impl LanguageRegistry { let this = self.clone(); let adapter = language.adapter.clone()?; - let background = cx.background().clone(); let lsp_binary_statuses = self.lsp_binary_statuses_tx.clone(); let login_shell_env_loaded = self.login_shell_env_loaded.clone(); - Some(cx.background().spawn(async move { + Some(cx.spawn(|cx| async move { login_shell_env_loaded.await; let server_binary_path = this .lsp_binary_paths @@ -328,8 +325,7 @@ impl LanguageRegistry { &server_binary_path, server_args, &root_path, - adapter.initialization_options(), - background, + cx, )?; Ok(server) })) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 51a68b83c8997747ffe0880fdab7f9d597417008..6d89b5e8706cb8b05c7919d930f8ec2c2afaa7fc 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -1,15 +1,17 @@ +pub use lsp_types::*; + use anyhow::{anyhow, Context, Result}; use collections::HashMap; use futures::{channel::oneshot, io::BufWriter, AsyncRead, AsyncWrite}; -use gpui::{executor, Task}; -use parking_lot::{Mutex, RwLock}; +use gpui::{executor, AsyncAppContext, Task}; +use parking_lot::Mutex; use postage::{barrier, prelude::Stream}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_json::{json, value::RawValue, Value}; use smol::{ channel, io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader}, - process::Command, + process, }; use std::{ future::Future, @@ -22,15 +24,12 @@ use std::{ }, }; use std::{path::Path, process::Stdio}; -use util::TryFutureExt; - -pub use lsp_types::*; +use util::{ResultExt, TryFutureExt}; const JSON_RPC_VERSION: &'static str = "2.0"; const CONTENT_LEN_HEADER: &'static str = "Content-Length: "; -type NotificationHandler = - Box, &str, &mut channel::Sender>) -> Result<()>>; +type NotificationHandler = Box, &str, AsyncAppContext)>; type ResponseHandler = Box)>; pub struct LanguageServer { @@ -39,18 +38,17 @@ pub struct LanguageServer { outbound_tx: channel::Sender>, name: String, capabilities: ServerCapabilities, - notification_handlers: Arc>>, + notification_handlers: Arc>>, response_handlers: Arc>>, executor: Arc, io_tasks: Mutex>, Task>)>>, output_done_rx: Mutex>, root_path: PathBuf, - options: Option, } pub struct Subscription { method: &'static str, - notification_handlers: Arc>>, + notification_handlers: Arc>>, } #[derive(Serialize, Deserialize)] @@ -61,18 +59,6 @@ struct Request<'a, T> { params: T, } -#[cfg(any(test, feature = "test-support"))] -#[derive(Deserialize)] -struct AnyRequest<'a> { - id: usize, - #[serde(borrow)] - jsonrpc: &'a str, - #[serde(borrow)] - method: &'a str, - #[serde(borrow)] - params: &'a RawValue, -} - #[derive(Serialize, Deserialize)] struct AnyResponse<'a> { id: usize, @@ -85,7 +71,8 @@ struct AnyResponse<'a> { #[derive(Serialize)] struct Response { id: usize, - result: T, + result: Option, + error: Option, } #[derive(Serialize, Deserialize)] @@ -118,15 +105,14 @@ impl LanguageServer { binary_path: &Path, args: &[&str], root_path: &Path, - options: Option, - background: Arc, + cx: AsyncAppContext, ) -> Result { let working_dir = if root_path.is_dir() { root_path } else { root_path.parent().unwrap_or(Path::new("/")) }; - let mut server = Command::new(binary_path) + let mut server = process::Command::new(binary_path) .current_dir(working_dir) .args(args) .stdin(Stdio::piped()) @@ -136,95 +122,91 @@ impl LanguageServer { let stdin = server.stdin.take().unwrap(); let stdout = server.stdout.take().unwrap(); let mut server = - Self::new_internal(server_id, stdin, stdout, root_path, options, background); + Self::new_internal(server_id, stdin, stdout, root_path, cx, |notification| { + log::info!( + "unhandled notification {}:\n{}", + notification.method, + serde_json::to_string_pretty( + &Value::from_str(notification.params.get()).unwrap() + ) + .unwrap() + ); + }); if let Some(name) = binary_path.file_name() { server.name = name.to_string_lossy().to_string(); } Ok(server) } - fn new_internal( + fn new_internal( server_id: usize, stdin: Stdin, stdout: Stdout, root_path: &Path, - options: Option, - executor: Arc, + cx: AsyncAppContext, + mut on_unhandled_notification: F, ) -> Self where Stdin: AsyncWrite + Unpin + Send + 'static, Stdout: AsyncRead + Unpin + Send + 'static, + F: FnMut(AnyNotification) + 'static + Send, { let mut stdin = BufWriter::new(stdin); let mut stdout = BufReader::new(stdout); let (outbound_tx, outbound_rx) = channel::unbounded::>(); let notification_handlers = - Arc::new(RwLock::new(HashMap::<_, NotificationHandler>::default())); + Arc::new(Mutex::new(HashMap::<_, NotificationHandler>::default())); let response_handlers = Arc::new(Mutex::new(HashMap::<_, ResponseHandler>::default())); - let input_task = executor.spawn( - { - let notification_handlers = notification_handlers.clone(); - let response_handlers = response_handlers.clone(); - let mut outbound_tx = outbound_tx.clone(); - async move { - let _clear_response_handlers = ClearResponseHandlers(response_handlers.clone()); - let mut buffer = Vec::new(); - loop { - buffer.clear(); - stdout.read_until(b'\n', &mut buffer).await?; - stdout.read_until(b'\n', &mut buffer).await?; - let message_len: usize = std::str::from_utf8(&buffer)? - .strip_prefix(CONTENT_LEN_HEADER) - .ok_or_else(|| anyhow!("invalid header"))? - .trim_end() - .parse()?; - - buffer.resize(message_len, 0); - stdout.read_exact(&mut buffer).await?; - log::trace!("incoming message:{}", String::from_utf8_lossy(&buffer)); - - if let Ok(AnyNotification { id, method, params }) = - serde_json::from_slice(&buffer) - { - if let Some(handler) = notification_handlers.write().get_mut(method) { - if let Err(e) = handler(id, params.get(), &mut outbound_tx) { - log::error!("error handling {} message: {:?}", method, e); - } + let input_task = cx.spawn(|cx| { + let notification_handlers = notification_handlers.clone(); + let response_handlers = response_handlers.clone(); + async move { + let _clear_response_handlers = ClearResponseHandlers(response_handlers.clone()); + let mut buffer = Vec::new(); + loop { + buffer.clear(); + stdout.read_until(b'\n', &mut buffer).await?; + stdout.read_until(b'\n', &mut buffer).await?; + let message_len: usize = std::str::from_utf8(&buffer)? + .strip_prefix(CONTENT_LEN_HEADER) + .ok_or_else(|| anyhow!("invalid header"))? + .trim_end() + .parse()?; + + buffer.resize(message_len, 0); + stdout.read_exact(&mut buffer).await?; + log::trace!("incoming message:{}", String::from_utf8_lossy(&buffer)); + + if let Ok(msg) = serde_json::from_slice::(&buffer) { + if let Some(handler) = notification_handlers.lock().get_mut(msg.method) { + handler(msg.id, msg.params.get(), cx.clone()); + } else { + on_unhandled_notification(msg); + } + } else if let Ok(AnyResponse { id, error, result }) = + serde_json::from_slice(&buffer) + { + if let Some(handler) = response_handlers.lock().remove(&id) { + if let Some(error) = error { + handler(Err(error)); + } else if let Some(result) = result { + handler(Ok(result.get())); } else { - log::info!( - "unhandled notification {}:\n{}", - method, - serde_json::to_string_pretty( - &Value::from_str(params.get()).unwrap() - ) - .unwrap() - ); - } - } else if let Ok(AnyResponse { id, error, result }) = - serde_json::from_slice(&buffer) - { - if let Some(handler) = response_handlers.lock().remove(&id) { - if let Some(error) = error { - handler(Err(error)); - } else if let Some(result) = result { - handler(Ok(result.get())); - } else { - handler(Ok("null")); - } + handler(Ok("null")); } - } else { - return Err(anyhow!( - "failed to deserialize message:\n{}", - std::str::from_utf8(&buffer)? - )); } + } else { + return Err(anyhow!( + "failed to deserialize message:\n{}", + std::str::from_utf8(&buffer)? + )); } } } - .log_err(), - ); + .log_err() + }); let (output_done_tx, output_done_rx) = barrier::channel(); - let output_task = executor.spawn({ + let output_task = cx.background().spawn({ let response_handlers = response_handlers.clone(); async move { let _clear_response_handlers = ClearResponseHandlers(response_handlers); @@ -253,18 +235,15 @@ impl LanguageServer { capabilities: Default::default(), next_id: Default::default(), outbound_tx, - executor: executor.clone(), + executor: cx.background().clone(), io_tasks: Mutex::new(Some((input_task, output_task))), output_done_rx: Mutex::new(Some(output_done_rx)), root_path: root_path.to_path_buf(), - options, } } - pub async fn initialize(mut self) -> Result> { - let options = self.options.take(); - let mut this = Arc::new(self); - let root_uri = Url::from_file_path(&this.root_path).unwrap(); + pub async fn initialize(mut self, options: Option) -> Result> { + let root_uri = Url::from_file_path(&self.root_path).unwrap(); #[allow(deprecated)] let params = InitializeParams { process_id: Default::default(), @@ -290,12 +269,13 @@ impl LanguageServer { value_set: vec![ CodeActionKind::REFACTOR.as_str().into(), CodeActionKind::QUICKFIX.as_str().into(), + CodeActionKind::SOURCE.as_str().into(), ], }, }), data_support: Some(true), resolve_support: Some(CodeActionCapabilityResolveSupport { - properties: vec!["edit".to_string()], + properties: vec!["edit".to_string(), "command".to_string()], }), ..Default::default() }), @@ -326,16 +306,14 @@ impl LanguageServer { locale: Default::default(), }; - let response = this.request::(params).await?; - { - let this = Arc::get_mut(&mut this).unwrap(); - if let Some(info) = response.server_info { - this.name = info.name; - } - this.capabilities = response.capabilities; + let response = self.request::(params).await?; + if let Some(info) = response.server_info { + self.name = info.name; } - this.notify::(InitializedParams {})?; - Ok(this) + self.capabilities = response.capabilities; + + self.notify::(InitializedParams {})?; + Ok(Arc::new(self)) } pub fn shutdown(&self) -> Option>> { @@ -370,37 +348,42 @@ impl LanguageServer { } } - pub fn on_notification(&mut self, f: F) -> Subscription + #[must_use] + pub fn on_notification(&self, f: F) -> Subscription where T: notification::Notification, - F: 'static + Send + Sync + FnMut(T::Params), + F: 'static + Send + FnMut(T::Params, AsyncAppContext), { self.on_custom_notification(T::METHOD, f) } - pub fn on_request(&mut self, f: F) -> Subscription + #[must_use] + pub fn on_request(&self, f: F) -> Subscription where T: request::Request, - F: 'static + Send + Sync + FnMut(T::Params) -> Result, + T::Params: 'static + Send, + F: 'static + Send + FnMut(T::Params, AsyncAppContext) -> Fut, + Fut: 'static + Future>, { self.on_custom_request(T::METHOD, f) } - pub fn on_custom_notification( - &mut self, - method: &'static str, - mut f: F, - ) -> Subscription + pub fn remove_request_handler(&self) { + self.notification_handlers.lock().remove(T::METHOD); + } + + #[must_use] + pub fn on_custom_notification(&self, method: &'static str, mut f: F) -> Subscription where - F: 'static + Send + Sync + FnMut(Params), + F: 'static + Send + FnMut(Params, AsyncAppContext), Params: DeserializeOwned, { - let prev_handler = self.notification_handlers.write().insert( + let prev_handler = self.notification_handlers.lock().insert( method, - Box::new(move |_, params, _| { - let params = serde_json::from_str(params)?; - f(params); - Ok(()) + Box::new(move |_, params, cx| { + if let Some(params) = serde_json::from_str(params).log_err() { + f(params, cx); + } }), ); assert!( @@ -413,26 +396,52 @@ impl LanguageServer { } } - pub fn on_custom_request( - &mut self, + #[must_use] + pub fn on_custom_request( + &self, method: &'static str, mut f: F, ) -> Subscription where - F: 'static + Send + Sync + FnMut(Params) -> Result, - Params: DeserializeOwned, + F: 'static + Send + FnMut(Params, AsyncAppContext) -> Fut, + Fut: 'static + Future>, + Params: DeserializeOwned + Send + 'static, Res: Serialize, { - let prev_handler = self.notification_handlers.write().insert( + let outbound_tx = self.outbound_tx.clone(); + let prev_handler = self.notification_handlers.lock().insert( method, - Box::new(move |id, params, tx| { + Box::new(move |id, params, cx| { if let Some(id) = id { - let params = serde_json::from_str(params)?; - let result = f(params)?; - let response = serde_json::to_vec(&Response { id, result })?; - tx.try_send(response)?; + if let Some(params) = serde_json::from_str(params).log_err() { + let response = f(params, cx.clone()); + cx.foreground() + .spawn({ + let outbound_tx = outbound_tx.clone(); + async move { + let response = match response.await { + Ok(result) => Response { + id, + result: Some(result), + error: None, + }, + Err(error) => Response { + id, + result: None, + error: Some(Error { + message: error.to_string(), + }), + }, + }; + if let Some(response) = serde_json::to_vec(&response).log_err() + { + outbound_tx.try_send(response).ok(); + } + } + }) + .detach(); + } } - Ok(()) }), ); assert!( @@ -458,7 +467,7 @@ impl LanguageServer { } pub fn request( - self: &Arc, + &self, params: T::Params, ) -> impl Future> where @@ -549,36 +558,16 @@ impl Subscription { impl Drop for Subscription { fn drop(&mut self) { - self.notification_handlers.write().remove(self.method); + self.notification_handlers.lock().remove(self.method); } } #[cfg(any(test, feature = "test-support"))] pub struct FakeLanguageServer { - handlers: FakeLanguageServerHandlers, - outgoing_tx: futures::channel::mpsc::UnboundedSender>, - incoming_rx: futures::channel::mpsc::UnboundedReceiver>, - _input_task: Task>, - _output_task: Task>, + server: Arc, + notifications_rx: channel::Receiver<(String, String)>, } -#[cfg(any(test, feature = "test-support"))] -type FakeLanguageServerHandlers = Arc< - Mutex< - HashMap< - &'static str, - Box< - dyn Send - + FnMut( - usize, - &[u8], - gpui::AsyncAppContext, - ) -> futures::future::BoxFuture<'static, Vec>, - >, - >, - >, ->; - #[cfg(any(test, feature = "test-support"))] impl LanguageServer { pub fn full_capabilities() -> ServerCapabilities { @@ -591,177 +580,101 @@ impl LanguageServer { } } - pub fn fake(cx: &mut gpui::MutableAppContext) -> (Self, FakeLanguageServer) { + pub fn fake(cx: AsyncAppContext) -> (Self, FakeLanguageServer) { Self::fake_with_capabilities(Self::full_capabilities(), cx) } pub fn fake_with_capabilities( capabilities: ServerCapabilities, - cx: &mut gpui::MutableAppContext, + cx: AsyncAppContext, ) -> (Self, FakeLanguageServer) { let (stdin_writer, stdin_reader) = async_pipe::pipe(); let (stdout_writer, stdout_reader) = async_pipe::pipe(); + let (notifications_tx, notifications_rx) = channel::unbounded(); - let mut fake = FakeLanguageServer::new(stdin_reader, stdout_writer, cx); + let server = Self::new_internal( + 0, + stdin_writer, + stdout_reader, + Path::new("/"), + cx.clone(), + |_| {}, + ); + let fake = FakeLanguageServer { + server: Arc::new(Self::new_internal( + 0, + stdout_writer, + stdin_reader, + Path::new("/"), + cx.clone(), + move |msg| { + notifications_tx + .try_send((msg.method.to_string(), msg.params.get().to_string())) + .ok(); + }, + )), + notifications_rx, + }; fake.handle_request::({ let capabilities = capabilities.clone(); move |_, _| { let capabilities = capabilities.clone(); async move { - InitializeResult { + Ok(InitializeResult { capabilities, ..Default::default() - } + }) } } }); - let executor = cx.background().clone(); - let server = Self::new_internal( - 0, - stdin_writer, - stdout_reader, - Path::new("/"), - None, - executor, - ); (server, fake) } } #[cfg(any(test, feature = "test-support"))] impl FakeLanguageServer { - fn new( - stdin: async_pipe::PipeReader, - stdout: async_pipe::PipeWriter, - cx: &mut gpui::MutableAppContext, - ) -> Self { - use futures::StreamExt as _; - - let (incoming_tx, incoming_rx) = futures::channel::mpsc::unbounded(); - let (outgoing_tx, mut outgoing_rx) = futures::channel::mpsc::unbounded(); - let handlers = FakeLanguageServerHandlers::default(); - - let input_task = cx.spawn(|cx| { - let handlers = handlers.clone(); - let outgoing_tx = outgoing_tx.clone(); - async move { - let mut buffer = Vec::new(); - let mut stdin = smol::io::BufReader::new(stdin); - while Self::receive(&mut stdin, &mut buffer).await.is_ok() { - cx.background().simulate_random_delay().await; - - if let Ok(request) = serde_json::from_slice::(&buffer) { - assert_eq!(request.jsonrpc, JSON_RPC_VERSION); - - let response; - if let Some(handler) = handlers.lock().get_mut(request.method) { - response = - handler(request.id, request.params.get().as_bytes(), cx.clone()) - .await; - log::debug!("handled lsp request. method:{}", request.method); - } else { - response = serde_json::to_vec(&AnyResponse { - id: request.id, - error: Some(Error { - message: "no handler".to_string(), - }), - result: None, - }) - .unwrap(); - log::debug!("unhandled lsp request. method:{}", request.method); - } - outgoing_tx.unbounded_send(response)?; - } else { - incoming_tx.unbounded_send(buffer.clone())?; - } - } - Ok::<_, anyhow::Error>(()) - } - }); - - let output_task = cx.background().spawn(async move { - let mut stdout = smol::io::BufWriter::new(stdout); - while let Some(message) = outgoing_rx.next().await { - stdout.write_all(CONTENT_LEN_HEADER.as_bytes()).await?; - stdout - .write_all((format!("{}", message.len())).as_bytes()) - .await?; - stdout.write_all("\r\n\r\n".as_bytes()).await?; - stdout.write_all(&message).await?; - stdout.flush().await?; - } - Ok(()) - }); - - Self { - outgoing_tx, - incoming_rx, - handlers, - _input_task: input_task, - _output_task: output_task, - } - } - - pub fn notify(&mut self, params: T::Params) { - let message = serde_json::to_vec(&Notification { - jsonrpc: JSON_RPC_VERSION, - method: T::METHOD, - params, - }) - .unwrap(); - self.outgoing_tx.unbounded_send(message).unwrap(); + pub fn notify(&self, params: T::Params) { + self.server.notify::(params).ok(); } pub async fn receive_notification(&mut self) -> T::Params { use futures::StreamExt as _; loop { - let bytes = self.incoming_rx.next().await.unwrap(); - if let Ok(notification) = serde_json::from_slice::>(&bytes) { - assert_eq!(notification.method, T::METHOD); - return notification.params; + let (method, params) = self.notifications_rx.next().await.unwrap(); + if &method == T::METHOD { + return serde_json::from_str::(¶ms).unwrap(); } else { - log::info!( - "skipping message in fake language server {:?}", - std::str::from_utf8(&bytes) - ); + log::info!("skipping message in fake language server {:?}", params); } } } pub fn handle_request( - &mut self, + &self, mut handler: F, ) -> futures::channel::mpsc::UnboundedReceiver<()> where T: 'static + request::Request, + T::Params: 'static + Send, F: 'static + Send + FnMut(T::Params, gpui::AsyncAppContext) -> Fut, - Fut: 'static + Send + Future, + Fut: 'static + Send + Future>, { - use futures::FutureExt as _; - let (responded_tx, responded_rx) = futures::channel::mpsc::unbounded(); - self.handlers.lock().insert( - T::METHOD, - Box::new(move |id, params, cx| { - let result = handler(serde_json::from_slice::(params).unwrap(), cx); + self.server.remove_request_handler::(); + self.server + .on_request::(move |params, cx| { + let result = handler(params, cx.clone()); let responded_tx = responded_tx.clone(); async move { + cx.background().simulate_random_delay().await; let result = result.await; - let result = serde_json::to_string(&result).unwrap(); - let result = serde_json::from_str::<&RawValue>(&result).unwrap(); - let response = AnyResponse { - id, - error: None, - result: Some(result), - }; responded_tx.unbounded_send(()).ok(); - serde_json::to_vec(&response).unwrap() + result } - .boxed() - }), - ); + }) + .detach(); responded_rx } @@ -769,7 +682,7 @@ impl FakeLanguageServer { where T: 'static + request::Request, { - self.handlers.lock().remove(T::METHOD); + self.server.remove_request_handler::(); } pub async fn start_progress(&mut self, token: impl Into) { @@ -785,25 +698,6 @@ impl FakeLanguageServer { value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(Default::default())), }); } - - async fn receive( - stdin: &mut smol::io::BufReader, - buffer: &mut Vec, - ) -> Result<()> { - buffer.clear(); - stdin.read_until(b'\n', buffer).await?; - stdin.read_until(b'\n', buffer).await?; - let message_len: usize = std::str::from_utf8(buffer) - .unwrap() - .strip_prefix(CONTENT_LEN_HEADER) - .ok_or_else(|| anyhow!("invalid content length header"))? - .trim_end() - .parse() - .unwrap(); - buffer.resize(message_len, 0); - stdin.read_exact(buffer).await?; - Ok(()) - } } struct ClearResponseHandlers(Arc>>); @@ -828,22 +722,22 @@ mod tests { #[gpui::test] async fn test_fake(cx: &mut TestAppContext) { - let (mut server, mut fake) = cx.update(LanguageServer::fake); + let (server, mut fake) = LanguageServer::fake(cx.to_async()); let (message_tx, message_rx) = channel::unbounded(); let (diagnostics_tx, diagnostics_rx) = channel::unbounded(); server - .on_notification::(move |params| { + .on_notification::(move |params, _| { message_tx.try_send(params).unwrap() }) .detach(); server - .on_notification::(move |params| { + .on_notification::(move |params, _| { diagnostics_tx.try_send(params).unwrap() }) .detach(); - let server = server.initialize().await.unwrap(); + let server = server.initialize(None).await.unwrap(); server .notify::(DidOpenTextDocumentParams { text_document: TextDocumentItem::new( @@ -878,7 +772,7 @@ mod tests { "file://b/c" ); - fake.handle_request::(|_, _| async move {}); + fake.handle_request::(|_, _| async move { Ok(()) }); drop(server); fake.receive_notification::().await; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 856405d620a0e00741b8e7976d4e560db6e3d6c5..036a3a29318ce7f0a393cdd489cc3cdcd5e829ae 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1325,7 +1325,7 @@ impl Project { cx, ); cx.spawn_weak(|this, mut cx| async move { - let mut language_server = language_server?.await.log_err()?; + let language_server = language_server?.await.log_err()?; let this = this.upgrade(&cx)?; let (language_server_events_tx, language_server_events_rx) = smol::channel::unbounded(); @@ -1333,7 +1333,7 @@ impl Project { language_server .on_notification::({ let language_server_events_tx = language_server_events_tx.clone(); - move |params| { + move |params, _| { language_server_events_tx .try_send(LanguageServerEvent::DiagnosticsUpdate(params)) .ok(); @@ -1342,31 +1342,33 @@ impl Project { .detach(); language_server - .on_request::({ + .on_request::({ let settings = this .read_with(&cx, |this, _| this.language_server_settings.clone()); - move |params| { - let settings = settings.lock(); - Ok(params - .items - .into_iter() - .map(|item| { - if let Some(section) = &item.section { - settings - .get(section) - .cloned() - .unwrap_or(serde_json::Value::Null) - } else { - settings.clone() - } - }) - .collect()) + move |params, _| { + let settings = settings.lock().clone(); + async move { + Ok(params + .items + .into_iter() + .map(|item| { + if let Some(section) = &item.section { + settings + .get(section) + .cloned() + .unwrap_or(serde_json::Value::Null) + } else { + settings.clone() + } + }) + .collect()) + } } }) .detach(); language_server - .on_notification::(move |params| { + .on_notification::(move |params, _| { let token = match params.token { lsp::NumberOrString::String(token) => token, lsp::NumberOrString::Number(token) => { @@ -1406,6 +1408,11 @@ impl Project { }) .detach(); + let language_server = language_server + .initialize(adapter.initialization_options()) + .await + .log_err()?; + // Process all the LSP events. cx.spawn(|mut cx| { let this = this.downgrade(); @@ -1424,7 +1431,6 @@ impl Project { }) .detach(); - let language_server = language_server.initialize().await.log_err()?; this.update(&mut cx, |this, cx| { this.language_servers .insert(key.clone(), (adapter, language_server.clone())); @@ -4974,9 +4980,9 @@ mod tests { }); let mut rust_shutdown_requests = fake_rust_server - .handle_request::(|_, _| future::ready(())); + .handle_request::(|_, _| future::ready(Ok(()))); let mut json_shutdown_requests = fake_json_server - .handle_request::(|_, _| future::ready(())); + .handle_request::(|_, _| future::ready(Ok(()))); futures::join!(rust_shutdown_requests.next(), json_shutdown_requests.next()); let mut fake_rust_server = fake_rust_servers.next().await.unwrap(); @@ -5917,19 +5923,11 @@ mod tests { .await; let buffer = project - .update(cx, |project, cx| { - project.open_buffer( - ProjectPath { - worktree_id, - path: Path::new("").into(), - }, - cx, - ) - }) + .update(cx, |project, cx| project.open_buffer((worktree_id, ""), cx)) .await .unwrap(); - let mut fake_server = fake_servers.next().await.unwrap(); + let fake_server = fake_servers.next().await.unwrap(); fake_server.handle_request::(|params, _| async move { let params = params.text_document_position_params; assert_eq!( @@ -5938,9 +5936,11 @@ mod tests { ); assert_eq!(params.position, lsp::Position::new(0, 22)); - Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location::new( - lsp::Url::from_file_path("/dir/a.rs").unwrap(), - lsp::Range::new(lsp::Position::new(0, 9), lsp::Position::new(0, 10)), + Ok(Some(lsp::GotoDefinitionResponse::Scalar( + lsp::Location::new( + lsp::Url::from_file_path("/dir/a.rs").unwrap(), + lsp::Range::new(lsp::Position::new(0, 9), lsp::Position::new(0, 10)), + ), ))) }); @@ -6854,7 +6854,7 @@ mod tests { .await .unwrap(); - let mut fake_server = fake_servers.next().await.unwrap(); + let fake_server = fake_servers.next().await.unwrap(); let response = project.update(cx, |project, cx| { project.prepare_rename(buffer.clone(), 7, cx) @@ -6863,10 +6863,10 @@ mod tests { .handle_request::(|params, _| async move { assert_eq!(params.text_document.uri.as_str(), "file:///dir/one.rs"); assert_eq!(params.position, lsp::Position::new(0, 7)); - Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( + Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( lsp::Position::new(0, 6), lsp::Position::new(0, 9), - ))) + )))) }) .next() .await @@ -6889,7 +6889,7 @@ mod tests { lsp::Position::new(0, 7) ); assert_eq!(params.new_name, "THREE"); - Some(lsp::WorkspaceEdit { + Ok(Some(lsp::WorkspaceEdit { changes: Some( [ ( @@ -6926,7 +6926,7 @@ mod tests { .collect(), ), ..Default::default() - }) + })) }) .next() .await diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index a010e55c32940e8f1ec5304e87d0798557b72f74..b158a17e877b8e61915fbb94b4459cf549ea6f99 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -2342,7 +2342,7 @@ mod tests { Editor::for_buffer(buffer_b.clone(), Some(project_b.clone()), cx) }); - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); buffer_b .condition(&cx_b, |buffer, _| !buffer.completion_triggers().is_empty()) .await; @@ -2368,7 +2368,7 @@ mod tests { lsp::Position::new(0, 14), ); - Some(lsp::CompletionResponse::Array(vec![ + Ok(Some(lsp::CompletionResponse::Array(vec![ lsp::CompletionItem { label: "first_method(…)".into(), detail: Some("fn(&mut self, B) -> C".into()), @@ -2395,7 +2395,7 @@ mod tests { insert_text_format: Some(lsp::InsertTextFormat::SNIPPET), ..Default::default() }, - ])) + ]))) }) .next() .await @@ -2425,7 +2425,7 @@ mod tests { fake_language_server.handle_request::( |params, _| async move { assert_eq!(params.label, "first_method(…)"); - lsp::CompletionItem { + Ok(lsp::CompletionItem { label: "first_method(…)".into(), detail: Some("fn(&mut self, B) -> C".into()), text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { @@ -2441,7 +2441,7 @@ mod tests { }]), insert_text_format: Some(lsp::InsertTextFormat::SNIPPET), ..Default::default() - } + }) }, ); @@ -2530,9 +2530,9 @@ mod tests { .await .unwrap(); - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::(|_, _| async move { - Some(vec![ + Ok(Some(vec![ lsp::TextEdit { range: lsp::Range::new(lsp::Position::new(0, 4), lsp::Position::new(0, 4)), new_text: "h".to_string(), @@ -2541,7 +2541,7 @@ mod tests { range: lsp::Range::new(lsp::Position::new(0, 7), lsp::Position::new(0, 7)), new_text: "y".to_string(), }, - ]) + ])) }); project_b @@ -2637,12 +2637,14 @@ mod tests { .unwrap(); // Request the definition of a symbol as the guest. - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::( |_, _| async move { - Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location::new( - lsp::Url::from_file_path("/root-2/b.rs").unwrap(), - lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)), + Ok(Some(lsp::GotoDefinitionResponse::Scalar( + lsp::Location::new( + lsp::Url::from_file_path("/root-2/b.rs").unwrap(), + lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)), + ), ))) }, ); @@ -2669,9 +2671,11 @@ mod tests { // the previous call to `definition`. fake_language_server.handle_request::( |_, _| async move { - Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location::new( - lsp::Url::from_file_path("/root-2/b.rs").unwrap(), - lsp::Range::new(lsp::Position::new(1, 6), lsp::Position::new(1, 11)), + Ok(Some(lsp::GotoDefinitionResponse::Scalar( + lsp::Location::new( + lsp::Url::from_file_path("/root-2/b.rs").unwrap(), + lsp::Range::new(lsp::Position::new(1, 6), lsp::Position::new(1, 11)), + ), ))) }, ); @@ -2778,14 +2782,14 @@ mod tests { .unwrap(); // Request references to a symbol as the guest. - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::( |params, _| async move { assert_eq!( params.text_document_position.text_document.uri.as_str(), "file:///root-1/one.rs" ); - Some(vec![ + Ok(Some(vec![ lsp::Location { uri: lsp::Url::from_file_path("/root-1/two.rs").unwrap(), range: lsp::Range::new( @@ -2807,7 +2811,7 @@ mod tests { lsp::Position::new(0, 40), ), }, - ]) + ])) }, ); @@ -3018,7 +3022,7 @@ mod tests { .unwrap(); // Request document highlights as the guest. - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::( |params, _| async move { assert_eq!( @@ -3033,7 +3037,7 @@ mod tests { params.text_document_position_params.position, lsp::Position::new(0, 34) ); - Some(vec![ + Ok(Some(vec![ lsp::DocumentHighlight { kind: Some(lsp::DocumentHighlightKind::WRITE), range: lsp::Range::new( @@ -3055,7 +3059,7 @@ mod tests { lsp::Position::new(0, 47), ), }, - ]) + ])) }, ); @@ -3162,11 +3166,11 @@ mod tests { .await .unwrap(); - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::( |_, _| async move { #[allow(deprecated)] - Some(vec![lsp::SymbolInformation { + Ok(Some(vec![lsp::SymbolInformation { name: "TWO".into(), location: lsp::Location { uri: lsp::Url::from_file_path("/code/crate-2/two.rs").unwrap(), @@ -3176,7 +3180,7 @@ mod tests { tags: None, container_name: None, deprecated: None, - }]) + }])) }, ); @@ -3292,12 +3296,14 @@ mod tests { .await .unwrap(); - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); fake_language_server.handle_request::( |_, _| async move { - Some(lsp::GotoDefinitionResponse::Scalar(lsp::Location::new( - lsp::Url::from_file_path("/root/b.rs").unwrap(), - lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)), + Ok(Some(lsp::GotoDefinitionResponse::Scalar( + lsp::Location::new( + lsp::Url::from_file_path("/root/b.rs").unwrap(), + lsp::Range::new(lsp::Position::new(0, 6), lsp::Position::new(0, 9)), + ), ))) }, ); @@ -3413,7 +3419,7 @@ mod tests { ); assert_eq!(params.range.start, lsp::Position::new(0, 0)); assert_eq!(params.range.end, lsp::Position::new(0, 0)); - None + Ok(None) }) .next() .await; @@ -3433,7 +3439,7 @@ mod tests { assert_eq!(params.range.start, lsp::Position::new(1, 31)); assert_eq!(params.range.end, lsp::Position::new(1, 31)); - Some(vec![lsp::CodeActionOrCommand::CodeAction( + Ok(Some(vec![lsp::CodeActionOrCommand::CodeAction( lsp::CodeAction { title: "Inline into all callers".to_string(), edit: Some(lsp::WorkspaceEdit { @@ -3475,7 +3481,7 @@ mod tests { })), ..Default::default() }, - )]) + )])) }) .next() .await; @@ -3498,7 +3504,7 @@ mod tests { .unwrap(); fake_language_server.handle_request::( |_, _| async move { - lsp::CodeAction { + Ok(lsp::CodeAction { title: "Inline into all callers".to_string(), edit: Some(lsp::WorkspaceEdit { changes: Some( @@ -3530,7 +3536,7 @@ mod tests { ..Default::default() }), ..Default::default() - } + }) }, ); @@ -3637,7 +3643,7 @@ mod tests { .unwrap() .downcast::() .unwrap(); - let mut fake_language_server = fake_language_servers.next().await.unwrap(); + let fake_language_server = fake_language_servers.next().await.unwrap(); // Move cursor to a location that can be renamed. let prepare_rename = editor_b.update(cx_b, |editor, cx| { @@ -3649,10 +3655,10 @@ mod tests { .handle_request::(|params, _| async move { assert_eq!(params.text_document.uri.as_str(), "file:///dir/one.rs"); assert_eq!(params.position, lsp::Position::new(0, 7)); - Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( + Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( lsp::Position::new(0, 6), lsp::Position::new(0, 9), - ))) + )))) }) .next() .await @@ -3686,7 +3692,7 @@ mod tests { lsp::Position::new(0, 6) ); assert_eq!(params.new_name, "THREE"); - Some(lsp::WorkspaceEdit { + Ok(Some(lsp::WorkspaceEdit { changes: Some( [ ( @@ -3723,7 +3729,7 @@ mod tests { .collect(), ), ..Default::default() - }) + })) }) .next() .await @@ -4894,36 +4900,38 @@ mod tests { move |fake_server: &mut FakeLanguageServer| { fake_server.handle_request::( |_, _| async move { - Some(lsp::CompletionResponse::Array(vec![lsp::CompletionItem { - text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { - range: lsp::Range::new( - lsp::Position::new(0, 0), - lsp::Position::new(0, 0), - ), - new_text: "the-new-text".to_string(), - })), - ..Default::default() - }])) + Ok(Some(lsp::CompletionResponse::Array(vec![ + lsp::CompletionItem { + text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { + range: lsp::Range::new( + lsp::Position::new(0, 0), + lsp::Position::new(0, 0), + ), + new_text: "the-new-text".to_string(), + })), + ..Default::default() + }, + ]))) }, ); fake_server.handle_request::( |_, _| async move { - Some(vec![lsp::CodeActionOrCommand::CodeAction( + Ok(Some(vec![lsp::CodeActionOrCommand::CodeAction( lsp::CodeAction { title: "the-code-action".to_string(), ..Default::default() }, - )]) + )])) }, ); fake_server.handle_request::( |params, _| async move { - Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( + Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new( params.position, params.position, - ))) + )))) }, ); @@ -4941,7 +4949,7 @@ mod tests { .map(|_| files.choose(&mut *rng).unwrap()) .collect::>(); log::info!("LSP: Returning definitions in files {:?}", &files); - Some(lsp::GotoDefinitionResponse::Array( + Ok(Some(lsp::GotoDefinitionResponse::Array( files .into_iter() .map(|file| lsp::Location { @@ -4949,7 +4957,7 @@ mod tests { range: Default::default(), }) .collect(), - )) + ))) } } }); @@ -4991,7 +4999,7 @@ mod tests { } else { None }; - async move { highlights } + async move { Ok(highlights) } } }); } From fed5d141bcd34e9188d4e9c5d88db6d4c8ec8ff5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 31 Mar 2022 22:03:52 -0700 Subject: [PATCH 18/68] Start work on applying code actions that use commands Co-Authored-By: Keith Simmons --- crates/project/src/project.rs | 326 +++++++++++++++++++++++++--------- 1 file changed, 243 insertions(+), 83 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 036a3a29318ce7f0a393cdd489cc3cdcd5e829ae..e37124dda01d4cd2f2fc1e3e8b089bd16dba1f3f 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -143,6 +143,7 @@ enum LanguageServerEvent { token: String, }, DiagnosticsUpdate(lsp::PublishDiagnosticsParams), + WorkspaceEdit(lsp::ApplyWorkspaceEditParams), } pub struct LanguageServerStatus { @@ -1367,6 +1368,24 @@ impl Project { }) .detach(); + language_server + .on_request::({ + let language_server_events_tx = language_server_events_tx.clone(); + move |params, _| { + language_server_events_tx + .try_send(LanguageServerEvent::WorkspaceEdit(params)) + .ok(); + async move { + Ok(lsp::ApplyWorkspaceEditResponse { + applied: true, + failed_change: None, + failure_reason: None, + }) + } + } + }) + .detach(); + language_server .on_notification::(move |params, _| { let token = match params.token { @@ -1416,12 +1435,20 @@ impl Project { // Process all the LSP events. cx.spawn(|mut cx| { let this = this.downgrade(); + let adapter = adapter.clone(); + let language_server = language_server.clone(); async move { while let Ok(event) = language_server_events_rx.recv().await { let this = this.upgrade(&cx)?; - this.update(&mut cx, |this, cx| { - this.on_lsp_event(server_id, event, &language, cx) - }); + Self::on_lsp_event( + this, + server_id, + &adapter, + &language_server, + event, + &mut cx, + ) + .await; // Don't starve the main thread when lots of events arrive all at once. smol::future::yield_now().await; @@ -1585,109 +1612,142 @@ impl Project { .detach(); } - fn on_lsp_event( - &mut self, + async fn on_lsp_event( + this: ModelHandle, language_server_id: usize, + adapter: &Arc, + language_server: &Arc, event: LanguageServerEvent, - language: &Arc, - cx: &mut ModelContext, + cx: &mut AsyncAppContext, ) { - let disk_diagnostics_token = language.disk_based_diagnostics_progress_token(); - let language_server_status = - if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) { - status - } else { - return; - }; - + let disk_based_diagnostics_progress_token = adapter.disk_based_diagnostics_progress_token(); match event { LanguageServerEvent::WorkStart { token } => { - if Some(token.as_str()) == disk_diagnostics_token { - language_server_status.pending_diagnostic_updates += 1; - if language_server_status.pending_diagnostic_updates == 1 { - self.disk_based_diagnostics_started(cx); - self.broadcast_language_server_update( + this.update(cx, |this, cx| { + let language_server_status = if let Some(status) = + this.language_server_statuses.get_mut(&language_server_id) + { + status + } else { + return; + }; + + if Some(token.as_str()) == disk_based_diagnostics_progress_token { + language_server_status.pending_diagnostic_updates += 1; + if language_server_status.pending_diagnostic_updates == 1 { + this.disk_based_diagnostics_started(cx); + this.broadcast_language_server_update( language_server_id, proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( proto::LspDiskBasedDiagnosticsUpdating {}, ), ); + } + } else { + this.on_lsp_work_start(language_server_id, token.clone(), cx); + this.broadcast_language_server_update( + language_server_id, + proto::update_language_server::Variant::WorkStart( + proto::LspWorkStart { token }, + ), + ); } - } else { - self.on_lsp_work_start(language_server_id, token.clone(), cx); - self.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::WorkStart(proto::LspWorkStart { - token, - }), - ); - } + }); } LanguageServerEvent::WorkProgress { token, progress } => { - if Some(token.as_str()) != disk_diagnostics_token { - self.on_lsp_work_progress( - language_server_id, - token.clone(), - progress.clone(), - cx, - ); - self.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::WorkProgress( - proto::LspWorkProgress { - token, - message: progress.message, - percentage: progress.percentage.map(|p| p as u32), - }, - ), - ); - } + this.update(cx, |this, cx| { + if Some(token.as_str()) != disk_based_diagnostics_progress_token { + this.on_lsp_work_progress( + language_server_id, + token.clone(), + progress.clone(), + cx, + ); + this.broadcast_language_server_update( + language_server_id, + proto::update_language_server::Variant::WorkProgress( + proto::LspWorkProgress { + token, + message: progress.message, + percentage: progress.percentage.map(|p| p as u32), + }, + ), + ); + } + }); } LanguageServerEvent::WorkEnd { token } => { - if Some(token.as_str()) == disk_diagnostics_token { - language_server_status.pending_diagnostic_updates -= 1; - if language_server_status.pending_diagnostic_updates == 0 { - self.disk_based_diagnostics_finished(cx); - self.broadcast_language_server_update( + this.update(cx, |this, cx| { + if Some(token.as_str()) == disk_based_diagnostics_progress_token { + let language_server_status = if let Some(status) = + this.language_server_statuses.get_mut(&language_server_id) + { + status + } else { + return; + }; + + language_server_status.pending_diagnostic_updates -= 1; + if language_server_status.pending_diagnostic_updates == 0 { + this.disk_based_diagnostics_finished(cx); + this.broadcast_language_server_update( + language_server_id, + proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( + proto::LspDiskBasedDiagnosticsUpdated {}, + ), + ); + } + } else { + this.on_lsp_work_end(language_server_id, token.clone(), cx); + this.broadcast_language_server_update( + language_server_id, + proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { + token, + }), + ); + } + }); + } + LanguageServerEvent::DiagnosticsUpdate(mut params) => { + this.update(cx, |this, cx| { + adapter.process_diagnostics(&mut params); + + if disk_based_diagnostics_progress_token.is_none() { + this.disk_based_diagnostics_started(cx); + this.broadcast_language_server_update( + language_server_id, + proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( + proto::LspDiskBasedDiagnosticsUpdating {}, + ), + ); + } + this.update_diagnostics(params, adapter.disk_based_diagnostic_sources(), cx) + .log_err(); + if disk_based_diagnostics_progress_token.is_none() { + this.disk_based_diagnostics_finished(cx); + this.broadcast_language_server_update( language_server_id, proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( proto::LspDiskBasedDiagnosticsUpdated {}, ), ); } - } else { - self.on_lsp_work_end(language_server_id, token.clone(), cx); - self.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { - token, - }), - ); - } + }); } - LanguageServerEvent::DiagnosticsUpdate(mut params) => { - language.process_diagnostics(&mut params); + LanguageServerEvent::WorkspaceEdit(params) => { + let transaction = Self::deserialize_workspace_edit( + this, + params.edit, + false, + adapter.clone(), + language_server.clone(), + cx, + ) + .await + .log_err(); - if disk_diagnostics_token.is_none() { - self.disk_based_diagnostics_started(cx); - self.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( - proto::LspDiskBasedDiagnosticsUpdating {}, - ), - ); - } - self.update_diagnostics(params, language.disk_based_diagnostic_sources(), cx) - .log_err(); - if disk_diagnostics_token.is_none() { - self.disk_based_diagnostics_finished(cx); - self.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( - proto::LspDiskBasedDiagnosticsUpdated {}, - ), - ); - } + // Check if there is a code action currently running, using the state that is + // set in `start_code_action`. If so, then store the transaction for later use. } } } @@ -2679,6 +2739,16 @@ impl Project { &mut cx, ) .await + } else if let Some(command) = action.lsp_action.command { + this.update(&mut cx, |this, _| this.start_code_action()); + lang_server + .request::(lsp::ExecuteCommandParams { + command: command.command, + arguments: command.arguments.unwrap_or_default(), + ..Default::default() + }) + .await?; + Ok(this.update(&mut cx, |this, cx| this.finish_code_action(cx))) } else { Ok(ProjectTransaction::default()) } @@ -2837,6 +2907,17 @@ impl Project { Ok(project_transaction) } + fn start_code_action(&mut self) { + // Set some state that will be read inside of `on_lsp_event` when handling a `WorkspaceEdit` + // event, and will cause the `ProjectTransaction` to be stored. + } + + fn finish_code_action(&mut self, cx: &mut ModelContext) -> ProjectTransaction { + // Retrieve all stored `ProjectTransactions` that have been received since `start_code_action` + // was called, and combine them together. + Default::default() + } + pub fn prepare_rename( &self, buffer: ModelHandle, @@ -5992,6 +6073,85 @@ mod tests { } } + #[gpui::test] + async fn test_apply_code_action(cx: &mut gpui::TestAppContext) { + let mut language = Language::new( + LanguageConfig { + name: "TypeScript".into(), + path_suffixes: vec!["ts".to_string()], + ..Default::default() + }, + None, + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + + let fs = FakeFs::new(cx.background()); + fs.insert_tree( + "/dir", + json!({ + "a.ts": "", + }), + ) + .await; + + let project = Project::test(fs, cx); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); + + let (tree, _) = project + .update(cx, |project, cx| { + project.find_or_create_local_worktree("/dir", true, cx) + }) + .await + .unwrap(); + let worktree_id = tree.read_with(cx, |tree, _| tree.id()); + cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) + .await; + + let buffer = project + .update(cx, |p, cx| p.open_buffer((worktree_id, "a.ts"), cx)) + .await + .unwrap(); + + let fake_server = fake_language_servers.next().await.unwrap(); + + let actions = project.update(cx, |project, cx| project.code_actions(&buffer, 0..0, cx)); + fake_server + .handle_request::(|params, _| async move { + Ok(Some(vec![ + lsp::CodeActionOrCommand::CodeAction(lsp::CodeAction { + title: "The code action".into(), + command: Some(lsp::Command { + title: "The command".into(), + command: "_the/command".into(), + arguments: Some(vec![json!("the-argument")]), + }), + ..Default::default() + }), + lsp::CodeActionOrCommand::CodeAction(lsp::CodeAction { + title: "two".into(), + ..Default::default() + }), + ])) + }) + .next() + .await; + + let action = actions.await.unwrap()[0].clone(); + let apply = project.update(cx, |project, cx| { + project.apply_code_action(buffer.clone(), action, true, cx) + }); + fake_server.handle_request::( + |action, _| async move { Ok(action) }, + ); + fake_server + .handle_request::(move |params, cx| async move { + // fake_server.send(); + Ok(Some(json!(null))) + }) + .next() + .await; + } + #[gpui::test] async fn test_save_file(cx: &mut gpui::TestAppContext) { let fs = FakeFs::new(cx.background()); From 65048760b2fdff02f44f916b07584ac8608061c6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 1 Apr 2022 14:01:56 +0200 Subject: [PATCH 19/68] Allow explicit reload of buffers via `Project::reload_buffers` --- crates/language/src/buffer.rs | 65 ++++++++++-------- crates/language/src/tests.rs | 8 ++- crates/project/src/project.rs | 94 ++++++++++++++++++++++++++ crates/rpc/proto/zed.proto | 85 +++++++++++++----------- crates/rpc/src/proto.rs | 4 ++ crates/rpc/src/rpc.rs | 2 +- crates/server/src/rpc.rs | 120 +++++++++++++++++++++++++++++++++- 7 files changed, 310 insertions(+), 68 deletions(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 0c1ce7c2285588a50d7bef75357e5ab26f37b990..f2c9d209b17aeddefc88de0ab7700a2b02130cf2 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -498,6 +498,30 @@ impl Buffer { cx.notify(); } + pub fn reload(&mut self, cx: &mut ModelContext) -> Task>> { + cx.spawn(|this, mut cx| async move { + if let Some((new_mtime, new_text)) = this.read_with(&cx, |this, cx| { + let file = this.file.as_ref()?.as_local()?; + Some((file.mtime(), file.load(cx))) + }) { + let new_text = new_text.await?; + let diff = this + .read_with(&cx, |this, cx| this.diff(new_text.into(), cx)) + .await; + this.update(&mut cx, |this, cx| { + if let Some(transaction) = this.apply_diff(diff, cx).cloned() { + this.did_reload(this.version(), new_mtime, cx); + Ok(Some(transaction)) + } else { + Ok(None) + } + }) + } else { + Ok(None) + } + }) + } + pub fn did_reload( &mut self, version: clock::Global, @@ -543,29 +567,8 @@ impl Buffer { file_changed = true; if !self.is_dirty() { - task = cx.spawn(|this, mut cx| { - async move { - let new_text = this.read_with(&cx, |this, cx| { - this.file - .as_ref() - .and_then(|file| file.as_local().map(|f| f.load(cx))) - }); - if let Some(new_text) = new_text { - let new_text = new_text.await?; - let diff = this - .read_with(&cx, |this, cx| this.diff(new_text.into(), cx)) - .await; - this.update(&mut cx, |this, cx| { - if this.apply_diff(diff, cx) { - this.did_reload(this.version(), new_mtime, cx); - } - }); - } - Ok(()) - } - .log_err() - .map(drop) - }); + let reload = self.reload(cx).log_err().map(drop); + task = cx.foreground().spawn(reload); } } } @@ -902,8 +905,13 @@ impl Buffer { }) } - pub(crate) fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext) -> bool { + pub(crate) fn apply_diff( + &mut self, + diff: Diff, + cx: &mut ModelContext, + ) -> Option<&Transaction> { if self.version == diff.base_version { + self.finalize_last_transaction(); self.start_transaction(); let mut offset = diff.start_offset; for (tag, len) in diff.changes { @@ -924,10 +932,13 @@ impl Buffer { } } } - self.end_transaction(cx); - true + if self.end_transaction(cx).is_some() { + self.finalize_last_transaction() + } else { + None + } } else { - false + None } } diff --git a/crates/language/src/tests.rs b/crates/language/src/tests.rs index 3eb87cefb62928573aa9087a39be8533f727bcc9..e980865cb432435ca8a2e1932e69a6a3a740fec3 100644 --- a/crates/language/src/tests.rs +++ b/crates/language/src/tests.rs @@ -136,12 +136,16 @@ async fn test_apply_diff(cx: &mut gpui::TestAppContext) { let text = "a\nccc\ndddd\nffffff\n"; let diff = buffer.read_with(cx, |b, cx| b.diff(text.into(), cx)).await; - buffer.update(cx, |b, cx| b.apply_diff(diff, cx)); + buffer.update(cx, |buffer, cx| { + buffer.apply_diff(diff, cx).unwrap(); + }); cx.read(|cx| assert_eq!(buffer.read(cx).text(), text)); let text = "a\n1\n\nccc\ndd2dd\nffffff\n"; let diff = buffer.read_with(cx, |b, cx| b.diff(text.into(), cx)).await; - buffer.update(cx, |b, cx| b.apply_diff(diff, cx)); + buffer.update(cx, |buffer, cx| { + buffer.apply_diff(diff, cx).unwrap(); + }); cx.read(|cx| assert_eq!(buffer.read(cx).text(), text)); } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 4ec856f19964166d42efd489520e242328ce7685..2316f4d80e24ad774336e87afad7aaf58f31669a 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -270,6 +270,7 @@ impl Project { client.add_model_message_handler(Self::handle_update_worktree); client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion); client.add_model_request_handler(Self::handle_apply_code_action); + client.add_model_request_handler(Self::handle_reload_buffers); client.add_model_request_handler(Self::handle_format_buffers); client.add_model_request_handler(Self::handle_get_code_actions); client.add_model_request_handler(Self::handle_get_completions); @@ -1973,6 +1974,70 @@ impl Project { Ok(()) } + pub fn reload_buffers( + &self, + buffers: HashSet>, + push_to_history: bool, + cx: &mut ModelContext, + ) -> Task> { + let mut local_buffers = Vec::new(); + let mut remote_buffers = None; + for buffer_handle in buffers { + let buffer = buffer_handle.read(cx); + if buffer.is_dirty() { + if let Some(file) = File::from_dyn(buffer.file()) { + if file.is_local() { + local_buffers.push(buffer_handle); + } else { + remote_buffers.get_or_insert(Vec::new()).push(buffer_handle); + } + } + } + } + + let remote_buffers = self.remote_id().zip(remote_buffers); + let client = self.client.clone(); + + cx.spawn(|this, mut cx| async move { + let mut project_transaction = ProjectTransaction::default(); + + if let Some((project_id, remote_buffers)) = remote_buffers { + let response = client + .request(proto::ReloadBuffers { + project_id, + buffer_ids: remote_buffers + .iter() + .map(|buffer| buffer.read_with(&cx, |buffer, _| buffer.remote_id())) + .collect(), + }) + .await? + .transaction + .ok_or_else(|| anyhow!("missing transaction"))?; + project_transaction = this + .update(&mut cx, |this, cx| { + this.deserialize_project_transaction(response, push_to_history, cx) + }) + .await?; + } + + for buffer in local_buffers { + let transaction = buffer + .update(&mut cx, |buffer, cx| buffer.reload(cx)) + .await?; + buffer.update(&mut cx, |buffer, cx| { + if let Some(transaction) = transaction { + if !push_to_history { + buffer.forget_transaction(transaction.id); + } + project_transaction.0.insert(cx.handle(), transaction); + } + }); + } + + Ok(project_transaction) + }) + } + pub fn format( &self, buffers: HashSet>, @@ -3667,6 +3732,35 @@ impl Project { }) } + async fn handle_reload_buffers( + this: ModelHandle, + envelope: TypedEnvelope, + _: Arc, + mut cx: AsyncAppContext, + ) -> Result { + let sender_id = envelope.original_sender_id()?; + let reload = this.update(&mut cx, |this, cx| { + let mut buffers = HashSet::default(); + for buffer_id in &envelope.payload.buffer_ids { + buffers.insert( + this.opened_buffers + .get(buffer_id) + .map(|buffer| buffer.upgrade(cx).unwrap()) + .ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))?, + ); + } + Ok::<_, anyhow::Error>(this.reload_buffers(buffers, false, cx)) + })?; + + let project_transaction = reload.await?; + let project_transaction = this.update(&mut cx, |this, cx| { + this.serialize_project_transaction_for_peer(project_transaction, sender_id, cx) + }); + Ok(proto::ReloadBuffersResponse { + transaction: Some(project_transaction), + }) + } + async fn handle_format_buffers( this: ModelHandle, envelope: TypedEnvelope, diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 9d25e66190b14bc7d4624885ec7da3dc57acb61b..e86a9a556edfabd9d37e8443c387a8eb012b956c 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -48,43 +48,45 @@ message Envelope { SaveBuffer save_buffer = 40; BufferSaved buffer_saved = 41; BufferReloaded buffer_reloaded = 42; - FormatBuffers format_buffers = 43; - FormatBuffersResponse format_buffers_response = 44; - GetCompletions get_completions = 45; - GetCompletionsResponse get_completions_response = 46; - ApplyCompletionAdditionalEdits apply_completion_additional_edits = 47; - ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 48; - GetCodeActions get_code_actions = 49; - GetCodeActionsResponse get_code_actions_response = 50; - ApplyCodeAction apply_code_action = 51; - ApplyCodeActionResponse apply_code_action_response = 52; - PrepareRename prepare_rename = 53; - PrepareRenameResponse prepare_rename_response = 54; - PerformRename perform_rename = 55; - PerformRenameResponse perform_rename_response = 56; - SearchProject search_project = 57; - SearchProjectResponse search_project_response = 58; - - GetChannels get_channels = 59; - GetChannelsResponse get_channels_response = 60; - JoinChannel join_channel = 61; - JoinChannelResponse join_channel_response = 62; - LeaveChannel leave_channel = 63; - SendChannelMessage send_channel_message = 64; - SendChannelMessageResponse send_channel_message_response = 65; - ChannelMessageSent channel_message_sent = 66; - GetChannelMessages get_channel_messages = 67; - GetChannelMessagesResponse get_channel_messages_response = 68; - - UpdateContacts update_contacts = 69; - - GetUsers get_users = 70; - GetUsersResponse get_users_response = 71; - - Follow follow = 72; - FollowResponse follow_response = 73; - UpdateFollowers update_followers = 74; - Unfollow unfollow = 75; + ReloadBuffers reload_buffers = 43; + ReloadBuffersResponse reload_buffers_response = 44; + FormatBuffers format_buffers = 45; + FormatBuffersResponse format_buffers_response = 46; + GetCompletions get_completions = 47; + GetCompletionsResponse get_completions_response = 48; + ApplyCompletionAdditionalEdits apply_completion_additional_edits = 49; + ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 50; + GetCodeActions get_code_actions = 51; + GetCodeActionsResponse get_code_actions_response = 52; + ApplyCodeAction apply_code_action = 53; + ApplyCodeActionResponse apply_code_action_response = 54; + PrepareRename prepare_rename = 55; + PrepareRenameResponse prepare_rename_response = 56; + PerformRename perform_rename = 57; + PerformRenameResponse perform_rename_response = 58; + SearchProject search_project = 59; + SearchProjectResponse search_project_response = 60; + + GetChannels get_channels = 61; + GetChannelsResponse get_channels_response = 62; + JoinChannel join_channel = 63; + JoinChannelResponse join_channel_response = 64; + LeaveChannel leave_channel = 65; + SendChannelMessage send_channel_message = 66; + SendChannelMessageResponse send_channel_message_response = 67; + ChannelMessageSent channel_message_sent = 68; + GetChannelMessages get_channel_messages = 69; + GetChannelMessagesResponse get_channel_messages_response = 70; + + UpdateContacts update_contacts = 71; + + GetUsers get_users = 72; + GetUsersResponse get_users_response = 73; + + Follow follow = 74; + FollowResponse follow_response = 75; + UpdateFollowers update_followers = 76; + Unfollow unfollow = 77; } } @@ -299,6 +301,15 @@ message BufferReloaded { Timestamp mtime = 4; } +message ReloadBuffers { + uint64 project_id = 1; + repeated uint64 buffer_ids = 2; +} + +message ReloadBuffersResponse { + ProjectTransaction transaction = 1; +} + message FormatBuffers { uint64 project_id = 1; repeated uint64 buffer_ids = 2; diff --git a/crates/rpc/src/proto.rs b/crates/rpc/src/proto.rs index 59d6773451fd2feebc28b17120e0b50a58de1127..a9f6b80f8e8d7895d705657d023f2b95a7c073a9 100644 --- a/crates/rpc/src/proto.rs +++ b/crates/rpc/src/proto.rs @@ -190,6 +190,8 @@ messages!( (Ping, Foreground), (RegisterProject, Foreground), (RegisterWorktree, Foreground), + (ReloadBuffers, Foreground), + (ReloadBuffersResponse, Foreground), (RemoveProjectCollaborator, Foreground), (SaveBuffer, Foreground), (SearchProject, Background), @@ -237,6 +239,7 @@ request_messages!( (PrepareRename, PrepareRenameResponse), (RegisterProject, RegisterProjectResponse), (RegisterWorktree, Ack), + (ReloadBuffers, ReloadBuffersResponse), (SaveBuffer, BufferSaved), (SearchProject, SearchProjectResponse), (SendChannelMessage, SendChannelMessageResponse), @@ -268,6 +271,7 @@ entity_messages!( OpenBufferForSymbol, PerformRename, PrepareRename, + ReloadBuffers, RemoveProjectCollaborator, SaveBuffer, SearchProject, diff --git a/crates/rpc/src/rpc.rs b/crates/rpc/src/rpc.rs index cfe780d5118c764a829cf047d288bc1e7a0b590e..9ee18faae2543b93e194f0e3c2a4fbe9e6604a84 100644 --- a/crates/rpc/src/rpc.rs +++ b/crates/rpc/src/rpc.rs @@ -5,4 +5,4 @@ pub mod proto; pub use conn::Connection; pub use peer::*; -pub const PROTOCOL_VERSION: u32 = 12; +pub const PROTOCOL_VERSION: u32 = 13; diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 374aaf6a7ec6820022c1802757cdabf3b51aa946..4d23f61ef74914a28c924b957bc113c8e94002a1 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -102,6 +102,7 @@ impl Server { .add_request_handler(Server::forward_project_request::) .add_request_handler(Server::forward_project_request::) .add_request_handler(Server::forward_project_request::) + .add_request_handler(Server::forward_project_request::) .add_request_handler(Server::forward_project_request::) .add_request_handler(Server::update_buffer) .add_message_handler(Server::update_buffer_file) @@ -1089,7 +1090,7 @@ mod tests { use gpui::{executor, geometry::vector::vec2f, ModelHandle, TestAppContext, ViewHandle}; use language::{ tree_sitter_rust, Diagnostic, DiagnosticEntry, Language, LanguageConfig, LanguageRegistry, - LanguageServerConfig, OffsetRangeExt, Point, ToLspPosition, + LanguageServerConfig, OffsetRangeExt, Point, Rope, ToLspPosition, }; use lsp; use parking_lot::Mutex; @@ -2460,6 +2461,123 @@ mod tests { .await; } + #[gpui::test(iterations = 10)] + async fn test_reloading_buffer_manually(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { + cx_a.foreground().forbid_parking(); + let lang_registry = Arc::new(LanguageRegistry::test()); + let fs = FakeFs::new(cx_a.background()); + + // Connect to a server as 2 clients. + let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; + let client_a = server.create_client(cx_a, "user_a").await; + let client_b = server.create_client(cx_b, "user_b").await; + + // Share a project as client A + fs.insert_tree( + "/a", + json!({ + ".zed.toml": r#"collaborators = ["user_b"]"#, + "a.rs": "let one = 1;", + }), + ) + .await; + let project_a = cx_a.update(|cx| { + Project::local( + client_a.clone(), + client_a.user_store.clone(), + lang_registry.clone(), + fs.clone(), + cx, + ) + }); + let (worktree_a, _) = project_a + .update(cx_a, |p, cx| { + p.find_or_create_local_worktree("/a", true, cx) + }) + .await + .unwrap(); + worktree_a + .read_with(cx_a, |tree, _| tree.as_local().unwrap().scan_complete()) + .await; + let project_id = project_a.update(cx_a, |p, _| p.next_remote_id()).await; + let worktree_id = worktree_a.read_with(cx_a, |tree, _| tree.id()); + project_a.update(cx_a, |p, cx| p.share(cx)).await.unwrap(); + let buffer_a = project_a + .update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)) + .await + .unwrap(); + + // Join the worktree as client B. + let project_b = Project::remote( + project_id, + client_b.clone(), + client_b.user_store.clone(), + lang_registry.clone(), + fs.clone(), + &mut cx_b.to_async(), + ) + .await + .unwrap(); + + let buffer_b = cx_b + .background() + .spawn(project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx))) + .await + .unwrap(); + buffer_b.update(cx_b, |buffer, cx| { + buffer.edit([4..7], "six", cx); + buffer.edit([10..11], "6", cx); + assert_eq!(buffer.text(), "let six = 6;"); + assert!(buffer.is_dirty()); + assert!(!buffer.has_conflict()); + }); + buffer_a + .condition(cx_a, |buffer, _| buffer.text() == "let six = 6;") + .await; + + fs.save(Path::new("/a/a.rs"), &Rope::from("let seven = 7;")) + .await + .unwrap(); + buffer_a + .condition(cx_a, |buffer, _| buffer.has_conflict()) + .await; + buffer_b + .condition(cx_b, |buffer, _| buffer.has_conflict()) + .await; + + project_b + .update(cx_b, |project, cx| { + project.reload_buffers(HashSet::from_iter([buffer_b.clone()]), true, cx) + }) + .await + .unwrap(); + buffer_a.read_with(cx_a, |buffer, _| { + assert_eq!(buffer.text(), "let seven = 7;"); + assert!(!buffer.is_dirty()); + assert!(!buffer.has_conflict()); + }); + buffer_b.read_with(cx_b, |buffer, _| { + assert_eq!(buffer.text(), "let seven = 7;"); + assert!(!buffer.is_dirty()); + assert!(!buffer.has_conflict()); + }); + + buffer_a.update(cx_a, |buffer, cx| { + // Undoing on the host is a no-op when the reload was initiated by the guest. + buffer.undo(cx); + assert_eq!(buffer.text(), "let seven = 7;"); + assert!(!buffer.is_dirty()); + assert!(!buffer.has_conflict()); + }); + buffer_b.update(cx_b, |buffer, cx| { + // Undoing on the guest rolls back the buffer to before it was reloaded but the conflict gets cleared. + buffer.undo(cx); + assert_eq!(buffer.text(), "let six = 6;"); + assert!(buffer.is_dirty()); + assert!(!buffer.has_conflict()); + }); + } + #[gpui::test(iterations = 10)] async fn test_formatting_buffer(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); From 703f1c3be086844405be3950a513e17b6eb4bed3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 1 Apr 2022 14:02:49 +0200 Subject: [PATCH 20/68] Introduce `workspace::Item::reload` to manually trigger a reload --- crates/diagnostics/src/diagnostics.rs | 8 ++++++++ crates/editor/src/items.rs | 25 +++++++++++++++++++++++++ crates/search/src/project_search.rs | 9 +++++++++ crates/workspace/src/workspace.rs | 15 +++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 56de434cf49e73c82ac19eefd7be36bdd3f5c71e..da50e99f1e5175d04900c4d0a4839479e1dd82c7 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -478,6 +478,14 @@ impl workspace::Item for ProjectDiagnosticsEditor { self.editor.save(project, cx) } + fn reload( + &mut self, + project: ModelHandle, + cx: &mut ViewContext, + ) -> Task> { + self.editor.reload(project, cx) + } + fn can_save_as(&self, _: &AppContext) -> bool { false } diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 79b25f8f60fa2ebe9e9832aac99b68c91b775f6b..67d5aee7731d9e23934849a8ee638de034bc82f6 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -371,6 +371,31 @@ impl Item for Editor { }) } + fn reload( + &mut self, + project: ModelHandle, + cx: &mut ViewContext, + ) -> Task> { + let buffer = self.buffer().clone(); + let buffers = self.buffer.read(cx).all_buffers(); + let reload_buffers = + project.update(cx, |project, cx| project.reload_buffers(buffers, true, cx)); + cx.spawn(|this, mut cx| async move { + let transaction = reload_buffers.log_err().await; + this.update(&mut cx, |editor, cx| { + editor.request_autoscroll(Autoscroll::Fit, cx) + }); + buffer.update(&mut cx, |buffer, _| { + if let Some(transaction) = transaction { + if !buffer.is_singleton() { + buffer.push_transaction(&transaction.0); + } + } + }); + Ok(()) + }) + } + fn should_activate_item_on_event(event: &Event) -> bool { matches!(event, Event::Activate) } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 65bb07ae46f4d6a1c43b409b6dc45bd40de2f139..745f23154fd98a77b3f20e79f1f4d513f235ebc5 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -280,6 +280,15 @@ impl Item for ProjectSearchView { unreachable!("save_as should not have been called") } + fn reload( + &mut self, + project: ModelHandle, + cx: &mut ViewContext, + ) -> Task> { + self.results_editor + .update(cx, |editor, cx| editor.reload(project, cx)) + } + fn clone_on_split(&self, cx: &mut ViewContext) -> Option where Self: Sized, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 9929cd9a51cd675e80953ad371ed1f94032e7459..073808e71a807cb1fb6dea48205e4f571738ecf7 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -237,6 +237,11 @@ pub trait Item: View { abs_path: PathBuf, cx: &mut ViewContext, ) -> Task>; + fn reload( + &mut self, + project: ModelHandle, + cx: &mut ViewContext, + ) -> Task>; fn should_activate_item_on_event(_: &Self::Event) -> bool { false } @@ -380,6 +385,8 @@ pub trait ItemHandle: 'static + fmt::Debug { abs_path: PathBuf, cx: &mut MutableAppContext, ) -> Task>; + fn reload(&self, project: ModelHandle, cx: &mut MutableAppContext) + -> Task>; fn act_as_type(&self, type_id: TypeId, cx: &AppContext) -> Option; fn to_followable_item_handle(&self, cx: &AppContext) -> Option>; } @@ -531,6 +538,14 @@ impl ItemHandle for ViewHandle { self.update(cx, |item, cx| item.save_as(project, abs_path, cx)) } + fn reload( + &self, + project: ModelHandle, + cx: &mut MutableAppContext, + ) -> Task> { + self.update(cx, |item, cx| item.reload(project, cx)) + } + fn is_dirty(&self, cx: &AppContext) -> bool { self.read(cx).is_dirty(cx) } From e93ab4db14e3f1f1bd2e991ce8a83c1e805e8f68 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 1 Apr 2022 14:32:41 +0200 Subject: [PATCH 21/68] Prompt before closing buffer with unsaved changes or conflicts --- crates/workspace/src/pane.rs | 331 +++++++++++++++++++++++++----- crates/workspace/src/workspace.rs | 7 +- crates/zed/src/zed.rs | 29 +-- 3 files changed, 305 insertions(+), 62 deletions(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index d48a5711a3373ce9aa8752fe2b78a5fcd46f2aec..33df9fd4c79285919330510a383befb94b6e5284 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1,16 +1,17 @@ use super::{ItemHandle, SplitDirection}; use crate::{toolbar::Toolbar, Item, Settings, WeakItemHandle, Workspace}; use collections::{HashMap, VecDeque}; +use futures::StreamExt; use gpui::{ action, elements::*, geometry::{rect::RectF, vector::vec2f}, keymap::Binding, platform::{CursorStyle, NavigationDirection}, - AppContext, Entity, MutableAppContext, Quad, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AppContext, Entity, ModelHandle, MutableAppContext, PromptLevel, Quad, RenderContext, Task, + View, ViewContext, ViewHandle, WeakViewHandle, }; -use project::{ProjectEntryId, ProjectPath}; +use project::{Project, ProjectEntryId, ProjectPath}; use std::{any::Any, cell::RefCell, cmp, mem, rc::Rc}; use util::ResultExt; @@ -37,13 +38,13 @@ pub fn init(cx: &mut MutableAppContext) { pane.activate_next_item(cx); }); cx.add_action(|pane: &mut Pane, _: &CloseActiveItem, cx| { - pane.close_active_item(cx); + pane.close_active_item(cx).detach(); }); cx.add_action(|pane: &mut Pane, _: &CloseInactiveItems, cx| { - pane.close_inactive_items(cx); + pane.close_inactive_items(cx).detach(); }); cx.add_action(|pane: &mut Pane, action: &CloseItem, cx| { - pane.close_item(action.0, cx); + pane.close_item(action.0, cx).detach(); }); cx.add_action(|pane: &mut Pane, action: &Split, cx| { pane.split(action.0, cx); @@ -97,6 +98,7 @@ pub struct Pane { active_item_index: usize, nav_history: Rc>, toolbar: ViewHandle, + project: ModelHandle, } pub struct ItemNavHistory { @@ -132,12 +134,13 @@ pub struct NavigationEntry { } impl Pane { - pub fn new(cx: &mut ViewContext) -> Self { + pub fn new(project: ModelHandle, cx: &mut ViewContext) -> Self { Self { items: Vec::new(), active_item_index: 0, nav_history: Default::default(), toolbar: cx.add_view(|_| Toolbar::new()), + project, } } @@ -403,65 +406,137 @@ impl Pane { self.activate_item(index, true, cx); } - pub fn close_active_item(&mut self, cx: &mut ViewContext) { - if !self.items.is_empty() { + pub fn close_active_item(&mut self, cx: &mut ViewContext) -> Task<()> { + if self.items.is_empty() { + Task::ready(()) + } else { self.close_item(self.items[self.active_item_index].id(), cx) } } - pub fn close_inactive_items(&mut self, cx: &mut ViewContext) { - if !self.items.is_empty() { + pub fn close_inactive_items(&mut self, cx: &mut ViewContext) -> Task<()> { + if self.items.is_empty() { + Task::ready(()) + } else { let active_item_id = self.items[self.active_item_index].id(); - self.close_items(cx, |id| id != active_item_id); + self.close_items(cx, move |id| id != active_item_id) } } - pub fn close_item(&mut self, view_id_to_close: usize, cx: &mut ViewContext) { - self.close_items(cx, |view_id| view_id == view_id_to_close); + pub fn close_item(&mut self, view_id_to_close: usize, cx: &mut ViewContext) -> Task<()> { + self.close_items(cx, move |view_id| view_id == view_id_to_close) } pub fn close_items( &mut self, cx: &mut ViewContext, - should_close: impl Fn(usize) -> bool, - ) { - let mut item_ix = 0; - let mut new_active_item_index = self.active_item_index; - self.items.retain(|item| { - if should_close(item.id()) { - if item_ix == self.active_item_index { - item.deactivated(cx); - } + should_close: impl 'static + Fn(usize) -> bool, + ) -> Task<()> { + const CONFLICT_MESSAGE: &'static str = "This file has changed on disk since you started editing it. Do you want to overwrite it?"; + const DIRTY_MESSAGE: &'static str = + "This file contains unsaved edits. Do you want to save it?"; + + let project = self.project.clone(); + cx.spawn(|this, mut cx| async move { + while let Some(item_to_close_ix) = this.read_with(&cx, |this, _| { + this.items.iter().position(|item| should_close(item.id())) + }) { + let item = + this.read_with(&cx, |this, _| this.items[item_to_close_ix].boxed_clone()); + if cx.read(|cx| item.can_save(cx)) { + if cx.read(|cx| item.has_conflict(cx)) { + let mut answer = this.update(&mut cx, |this, cx| { + this.activate_item(item_to_close_ix, true, cx); + cx.prompt( + PromptLevel::Warning, + CONFLICT_MESSAGE, + &["Overwrite", "Discard", "Cancel"], + ) + }); - if item_ix < self.active_item_index { - new_active_item_index -= 1; - } + match answer.next().await { + Some(0) => { + if cx + .update(|cx| item.save(project.clone(), cx)) + .await + .log_err() + .is_none() + { + break; + } + } + Some(1) => { + if cx + .update(|cx| item.reload(project.clone(), cx)) + .await + .log_err() + .is_none() + { + break; + } + } + _ => break, + } + } else if cx.read(|cx| item.is_dirty(cx)) { + let mut answer = this.update(&mut cx, |this, cx| { + this.activate_item(item_to_close_ix, true, cx); + cx.prompt( + PromptLevel::Warning, + DIRTY_MESSAGE, + &["Save", "Don't Save", "Cancel"], + ) + }); - let mut nav_history = self.nav_history.borrow_mut(); - if let Some(path) = item.project_path(cx) { - nav_history.paths_by_item.insert(item.id(), path); - } else { - nav_history.paths_by_item.remove(&item.id()); + match answer.next().await { + Some(0) => { + if cx + .update(|cx| item.save(project.clone(), cx)) + .await + .log_err() + .is_none() + { + break; + } + } + Some(1) => {} + _ => break, + } + } } - item_ix += 1; - false - } else { - item_ix += 1; - true + this.update(&mut cx, |this, cx| { + if let Some(item_ix) = this.items.iter().position(|i| i.id() == item.id()) { + this.items.remove(item_ix); + if item_ix == this.active_item_index { + item.deactivated(cx); + } + if item_ix < this.active_item_index { + this.active_item_index -= 1; + } + this.active_item_index = + cmp::min(this.active_item_index, this.items.len().saturating_sub(1)); + + let mut nav_history = this.nav_history.borrow_mut(); + if let Some(path) = item.project_path(cx) { + nav_history.paths_by_item.insert(item.id(), path); + } else { + nav_history.paths_by_item.remove(&item.id()); + } + } + }); } - }); - - if self.items.is_empty() { - cx.emit(Event::Remove); - } else { - self.active_item_index = cmp::min(new_active_item_index, self.items.len() - 1); - self.focus_active_item(cx); - self.activate(cx); - } - self.update_toolbar(cx); - cx.notify(); + this.update(&mut cx, |this, cx| { + if this.items.is_empty() { + cx.emit(Event::Remove); + } else { + this.focus_active_item(cx); + this.activate(cx); + } + this.update_toolbar(cx); + cx.notify(); + }) + }) } pub fn focus_active_item(&mut self, cx: &mut ViewContext) { @@ -743,3 +818,165 @@ impl NavHistory { } } } + +#[cfg(test)] +mod tests { + use crate::WorkspaceParams; + + use super::*; + use gpui::TestAppContext; + + #[gpui::test] + async fn test_close_items(cx: &mut TestAppContext) { + cx.foreground().forbid_parking(); + + let params = cx.update(WorkspaceParams::test); + let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); + let item1 = cx.add_view(window_id, |_| TestItem::new(false, true)); + let item2 = cx.add_view(window_id, |_| TestItem::new(true, true)); + let item3 = cx.add_view(window_id, |_| TestItem::new(false, true)); + let item4 = cx.add_view(window_id, |_| TestItem::new(true, false)); + let pane = workspace.update(cx, |workspace, cx| { + workspace.add_item(Box::new(item1.clone()), cx); + workspace.add_item(Box::new(item3.clone()), cx); + workspace.add_item(Box::new(item4.clone()), cx); + workspace.add_item(Box::new(item2.clone()), cx); + assert_eq!(workspace.active_item(cx).unwrap().id(), item2.id()); + + workspace.active_pane().clone() + }); + + let close_items = pane.update(cx, |pane, cx| { + let item1_id = item1.id(); + let item3_id = item3.id(); + let item4_id = item4.id(); + pane.close_items(cx, move |id| { + id == item1_id || id == item3_id || id == item4_id + }) + }); + + cx.foreground().run_until_parked(); + pane.read_with(cx, |pane, _| { + assert_eq!(pane.items.len(), 4); + assert_eq!(pane.active_item().unwrap().id(), item1.id()); + }); + + cx.simulate_prompt_answer(window_id, 0); + cx.foreground().run_until_parked(); + pane.read_with(cx, |pane, cx| { + assert_eq!(item1.read(cx).save_count, 1); + assert_eq!(item1.read(cx).reload_count, 0); + assert_eq!(pane.items.len(), 3); + assert_eq!(pane.active_item().unwrap().id(), item3.id()); + }); + + cx.simulate_prompt_answer(window_id, 1); + cx.foreground().run_until_parked(); + pane.read_with(cx, |pane, cx| { + assert_eq!(item3.read(cx).save_count, 0); + assert_eq!(item3.read(cx).reload_count, 1); + assert_eq!(pane.items.len(), 2); + assert_eq!(pane.active_item().unwrap().id(), item4.id()); + }); + + cx.simulate_prompt_answer(window_id, 0); + close_items.await; + pane.read_with(cx, |pane, cx| { + assert_eq!(item4.read(cx).save_count, 1); + assert_eq!(item4.read(cx).reload_count, 0); + assert_eq!(pane.items.len(), 1); + assert_eq!(pane.active_item().unwrap().id(), item2.id()); + }); + } + + struct TestItem { + is_dirty: bool, + has_conflict: bool, + save_count: usize, + reload_count: usize, + } + + impl TestItem { + fn new(is_dirty: bool, has_conflict: bool) -> Self { + Self { + save_count: 0, + reload_count: 0, + is_dirty, + has_conflict, + } + } + } + + impl Entity for TestItem { + type Event = (); + } + + impl View for TestItem { + fn ui_name() -> &'static str { + "TestItem" + } + + fn render(&mut self, _: &mut RenderContext) -> ElementBox { + Empty::new().boxed() + } + } + + impl Item for TestItem { + fn tab_content(&self, _: &theme::Tab, _: &AppContext) -> ElementBox { + Empty::new().boxed() + } + + fn project_path(&self, _: &AppContext) -> Option { + None + } + + fn project_entry_id(&self, _: &AppContext) -> Option { + None + } + + fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext) {} + + fn is_dirty(&self, _: &AppContext) -> bool { + self.is_dirty + } + + fn has_conflict(&self, _: &AppContext) -> bool { + self.has_conflict + } + + fn can_save(&self, _: &AppContext) -> bool { + true + } + + fn save( + &mut self, + _: ModelHandle, + _: &mut ViewContext, + ) -> Task> { + self.save_count += 1; + Task::ready(Ok(())) + } + + fn can_save_as(&self, _: &AppContext) -> bool { + false + } + + fn save_as( + &mut self, + _: ModelHandle, + _: std::path::PathBuf, + _: &mut ViewContext, + ) -> Task> { + unreachable!() + } + + fn reload( + &mut self, + _: ModelHandle, + _: &mut ViewContext, + ) -> Task> { + self.reload_count += 1; + Task::ready(Ok(())) + } + } +} diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 073808e71a807cb1fb6dea48205e4f571738ecf7..c447f3a5fd567c1f5f89a11f2e93edce632648b9 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -497,7 +497,8 @@ impl ItemHandle for ViewHandle { } if T::should_close_item_on_event(event) { - pane.update(cx, |pane, cx| pane.close_item(item.id(), cx)); + pane.update(cx, |pane, cx| pane.close_item(item.id(), cx)) + .detach(); return; } @@ -737,7 +738,7 @@ impl Workspace { }) .detach(); - let pane = cx.add_view(|cx| Pane::new(cx)); + let pane = cx.add_view(|cx| Pane::new(params.project.clone(), cx)); let pane_id = pane.id(); cx.observe(&pane, move |me, _, cx| { let active_entry = me.active_project_path(cx); @@ -1069,7 +1070,7 @@ impl Workspace { } fn add_pane(&mut self, cx: &mut ViewContext) -> ViewHandle { - let pane = cx.add_view(|cx| Pane::new(cx)); + let pane = cx.add_view(|cx| Pane::new(self.project.clone(), cx)); let pane_id = pane.id(); cx.observe(&pane, move |me, _, cx| { let active_entry = me.active_project_path(cx); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index c94f8a0e8164a5f1b7a9cbcd9229f1e65ed59593..24bdf4c0ef8e641216f995d7b23f5359bbfc5be6 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -867,12 +867,15 @@ mod tests { // Go forward to an item that has been closed, ensuring it gets re-opened at the same // location. - workspace.update(cx, |workspace, cx| { - workspace - .active_pane() - .update(cx, |pane, cx| pane.close_item(editor3.id(), cx)); - drop(editor3); - }); + workspace + .update(cx, |workspace, cx| { + let editor3_id = editor3.id(); + drop(editor3); + workspace + .active_pane() + .update(cx, |pane, cx| pane.close_item(editor3_id, cx)) + }) + .await; workspace .update(cx, |w, cx| Pane::go_forward(w, None, cx)) .await; @@ -884,15 +887,17 @@ mod tests { // Go back to an item that has been closed and removed from disk, ensuring it gets skipped. workspace .update(cx, |workspace, cx| { + let editor2_id = editor2.id(); + drop(editor2); workspace .active_pane() - .update(cx, |pane, cx| pane.close_item(editor2.id(), cx)); - drop(editor2); - app_state - .fs - .as_fake() - .remove_file(Path::new("/root/a/file2"), Default::default()) + .update(cx, |pane, cx| pane.close_item(editor2_id, cx)) }) + .await; + app_state + .fs + .as_fake() + .remove_file(Path::new("/root/a/file2"), Default::default()) .await .unwrap(); workspace From be677a8a4b76b9a974177508bbec69d78c9a3c77 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 1 Apr 2022 15:27:06 +0200 Subject: [PATCH 22/68] Don't assume the `CloseActiveItem` action is synchronous in test --- crates/zed/src/zed.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 24bdf4c0ef8e641216f995d7b23f5359bbfc5be6..00f57ccccb7bd6ebf34d89c91bcbc1c7fbf7100d 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -683,6 +683,8 @@ mod tests { #[gpui::test] async fn test_pane_actions(cx: &mut TestAppContext) { + cx.foreground().forbid_parking(); + cx.update(|cx| pane::init(cx)); let app_state = cx.update(test_app_state); app_state @@ -740,7 +742,9 @@ mod tests { assert_eq!(pane2_item.project_path(cx.as_ref()), Some(file1.clone())); cx.dispatch_action(window_id, vec![pane_2.id()], &workspace::CloseActiveItem); - let workspace = workspace.read(cx); + }); + cx.foreground().run_until_parked(); + workspace.read_with(cx, |workspace, _| { assert_eq!(workspace.panes().len(), 1); assert_eq!(workspace.active_pane(), &pane_1); }); From 56523b5775e780f2755e4683008d8b3c57f27de8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 10:16:26 -0700 Subject: [PATCH 23/68] Allow applying code actions that use commands Co-Authored-By: Antonio Scandurra --- crates/lsp/src/lsp.rs | 3 +- crates/project/src/project.rs | 83 +++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 24 deletions(-) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 6d89b5e8706cb8b05c7919d930f8ec2c2afaa7fc..f5fc98640d7400160b104ec6654d0260c3ffd25c 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -563,8 +563,9 @@ impl Drop for Subscription { } #[cfg(any(test, feature = "test-support"))] +#[derive(Clone)] pub struct FakeLanguageServer { - server: Arc, + pub server: Arc, notifications_rx: channel::Receiver<(String, String)>, } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e37124dda01d4cd2f2fc1e3e8b089bd16dba1f3f..4225f9657fbfcf351f1eb0d2efe1aa841278252a 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -64,6 +64,7 @@ pub struct Project { HashMap<(WorktreeId, LanguageServerName), Task>>>, language_server_statuses: BTreeMap, language_server_settings: Arc>, + last_workspace_edits_by_language_server: HashMap, next_language_server_id: usize, client: Arc, next_entry_id: Arc, @@ -346,6 +347,7 @@ impl Project { language_servers: Default::default(), started_language_servers: Default::default(), language_server_statuses: Default::default(), + last_workspace_edits_by_language_server: Default::default(), language_server_settings: Default::default(), next_language_server_id: 0, nonce: StdRng::from_entropy().gen(), @@ -433,6 +435,7 @@ impl Project { ) }) .collect(), + last_workspace_edits_by_language_server: Default::default(), next_language_server_id: 0, opened_buffers: Default::default(), buffer_snapshots: Default::default(), @@ -1736,18 +1739,21 @@ impl Project { } LanguageServerEvent::WorkspaceEdit(params) => { let transaction = Self::deserialize_workspace_edit( - this, + this.clone(), params.edit, - false, + true, adapter.clone(), language_server.clone(), cx, ) .await .log_err(); - - // Check if there is a code action currently running, using the state that is - // set in `start_code_action`. If so, then store the transaction for later use. + this.update(cx, |this, _| { + if let Some(transaction) = transaction { + this.last_workspace_edits_by_language_server + .insert(language_server_id, transaction); + } + }); } } } @@ -2740,7 +2746,6 @@ impl Project { ) .await } else if let Some(command) = action.lsp_action.command { - this.update(&mut cx, |this, _| this.start_code_action()); lang_server .request::(lsp::ExecuteCommandParams { command: command.command, @@ -2748,7 +2753,11 @@ impl Project { ..Default::default() }) .await?; - Ok(this.update(&mut cx, |this, cx| this.finish_code_action(cx))) + Ok(this.update(&mut cx, |this, _| { + this.last_workspace_edits_by_language_server + .remove(&lang_server.server_id()) + .unwrap_or_default() + })) } else { Ok(ProjectTransaction::default()) } @@ -2907,17 +2916,6 @@ impl Project { Ok(project_transaction) } - fn start_code_action(&mut self) { - // Set some state that will be read inside of `on_lsp_event` when handling a `WorkspaceEdit` - // event, and will cause the `ProjectTransaction` to be stored. - } - - fn finish_code_action(&mut self, cx: &mut ModelContext) -> ProjectTransaction { - // Retrieve all stored `ProjectTransactions` that have been received since `start_code_action` - // was called, and combine them together. - Default::default() - } - pub fn prepare_rename( &self, buffer: ModelHandle, @@ -6089,7 +6087,7 @@ mod tests { fs.insert_tree( "/dir", json!({ - "a.ts": "", + "a.ts": "a", }), ) .await; @@ -6116,7 +6114,7 @@ mod tests { let actions = project.update(cx, |project, cx| project.code_actions(&buffer, 0..0, cx)); fake_server - .handle_request::(|params, _| async move { + .handle_request::(|_, _| async move { Ok(Some(vec![ lsp::CodeActionOrCommand::CodeAction(lsp::CodeAction { title: "The code action".into(), @@ -6144,12 +6142,51 @@ mod tests { |action, _| async move { Ok(action) }, ); fake_server - .handle_request::(move |params, cx| async move { - // fake_server.send(); - Ok(Some(json!(null))) + .handle_request::({ + let fake = fake_server.clone(); + move |params, _| { + assert_eq!(params.command, "_the/command"); + let fake = fake.clone(); + async move { + fake.server + .request::( + lsp::ApplyWorkspaceEditParams { + label: None, + edit: lsp::WorkspaceEdit { + changes: Some( + [( + lsp::Url::from_file_path("/dir/a.ts").unwrap(), + vec![lsp::TextEdit { + range: lsp::Range::new( + lsp::Position::new(0, 0), + lsp::Position::new(0, 0), + ), + new_text: "X".into(), + }], + )] + .into_iter() + .collect(), + ), + ..Default::default() + }, + }, + ) + .await + .unwrap(); + Ok(Some(json!(null))) + } + } }) .next() .await; + + let transaction = apply.await.unwrap(); + assert!(transaction.0.contains_key(&buffer)); + buffer.update(cx, |buffer, cx| { + assert_eq!(buffer.text(), "Xa"); + buffer.undo(cx); + assert_eq!(buffer.text(), "a"); + }); } #[gpui::test] From ba009724dd89b2f5ace6eb505da2d17aca0e1ed2 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 11:59:21 -0700 Subject: [PATCH 24/68] Handle LSP apply workspace edit request fully before responding --- crates/editor/src/editor.rs | 2 + crates/project/src/project.rs | 366 ++++++++++++++++------------------ 2 files changed, 172 insertions(+), 196 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0dccce37a9e5461c113f79b89f3faa2cdcd04d8f..1135c9b260367a563add678c6a73a46b2d6d561e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2593,6 +2593,8 @@ impl Editor { } } } + } else { + return Ok(()); } let mut ranges_to_highlight = Vec::new(); diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 4225f9657fbfcf351f1eb0d2efe1aa841278252a..a8311ccf3b144589925ab966fbeaef10cb36122e 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -132,21 +132,6 @@ pub enum Event { CollaboratorLeft(PeerId), } -enum LanguageServerEvent { - WorkStart { - token: String, - }, - WorkProgress { - token: String, - progress: LanguageServerProgress, - }, - WorkEnd { - token: String, - }, - DiagnosticsUpdate(lsp::PublishDiagnosticsParams), - WorkspaceEdit(lsp::ApplyWorkspaceEditParams), -} - pub struct LanguageServerStatus { pub name: String, pub pending_work: BTreeMap, @@ -1330,17 +1315,30 @@ impl Project { ); cx.spawn_weak(|this, mut cx| async move { let language_server = language_server?.await.log_err()?; + let language_server = language_server + .initialize(adapter.initialization_options()) + .await + .log_err()?; let this = this.upgrade(&cx)?; - let (language_server_events_tx, language_server_events_rx) = - smol::channel::unbounded(); + let disk_based_diagnostics_progress_token = + adapter.disk_based_diagnostics_progress_token(); language_server .on_notification::({ - let language_server_events_tx = language_server_events_tx.clone(); - move |params, _| { - language_server_events_tx - .try_send(LanguageServerEvent::DiagnosticsUpdate(params)) - .ok(); + let this = this.downgrade(); + let adapter = adapter.clone(); + move |params, mut cx| { + if let Some(this) = this.upgrade(&cx) { + this.update(&mut cx, |this, cx| { + this.on_lsp_diagnostics_published( + server_id, + params, + &adapter, + disk_based_diagnostics_progress_token, + cx, + ); + }); + } } }) .detach(); @@ -1373,94 +1371,40 @@ impl Project { language_server .on_request::({ - let language_server_events_tx = language_server_events_tx.clone(); - move |params, _| { - language_server_events_tx - .try_send(LanguageServerEvent::WorkspaceEdit(params)) - .ok(); - async move { - Ok(lsp::ApplyWorkspaceEditResponse { - applied: true, - failed_change: None, - failure_reason: None, - }) - } + let this = this.downgrade(); + let adapter = adapter.clone(); + let language_server = language_server.clone(); + move |params, cx| { + Self::on_lsp_workspace_edit( + this, + params, + server_id, + adapter.clone(), + language_server.clone(), + cx, + ) } }) .detach(); language_server - .on_notification::(move |params, _| { - let token = match params.token { - lsp::NumberOrString::String(token) => token, - lsp::NumberOrString::Number(token) => { - log::info!("skipping numeric progress token {}", token); - return; + .on_notification::({ + let this = this.downgrade(); + move |params, mut cx| { + if let Some(this) = this.upgrade(&cx) { + this.update(&mut cx, |this, cx| { + this.on_lsp_progress( + params, + server_id, + disk_based_diagnostics_progress_token, + cx, + ); + }); } - }; - - match params.value { - lsp::ProgressParamsValue::WorkDone(progress) => match progress { - lsp::WorkDoneProgress::Begin(_) => { - language_server_events_tx - .try_send(LanguageServerEvent::WorkStart { token }) - .ok(); - } - lsp::WorkDoneProgress::Report(report) => { - language_server_events_tx - .try_send(LanguageServerEvent::WorkProgress { - token, - progress: LanguageServerProgress { - message: report.message, - percentage: report - .percentage - .map(|p| p as usize), - last_update_at: Instant::now(), - }, - }) - .ok(); - } - lsp::WorkDoneProgress::End(_) => { - language_server_events_tx - .try_send(LanguageServerEvent::WorkEnd { token }) - .ok(); - } - }, } }) .detach(); - let language_server = language_server - .initialize(adapter.initialization_options()) - .await - .log_err()?; - - // Process all the LSP events. - cx.spawn(|mut cx| { - let this = this.downgrade(); - let adapter = adapter.clone(); - let language_server = language_server.clone(); - async move { - while let Ok(event) = language_server_events_rx.recv().await { - let this = this.upgrade(&cx)?; - Self::on_lsp_event( - this, - server_id, - &adapter, - &language_server, - event, - &mut cx, - ) - .await; - - // Don't starve the main thread when lots of events arrive all at once. - smol::future::yield_now().await; - } - Some(()) - } - }) - .detach(); - this.update(&mut cx, |this, cx| { this.language_servers .insert(key.clone(), (adapter, language_server.clone())); @@ -1615,75 +1559,111 @@ impl Project { .detach(); } - async fn on_lsp_event( - this: ModelHandle, - language_server_id: usize, + fn on_lsp_diagnostics_published( + &mut self, + server_id: usize, + mut params: lsp::PublishDiagnosticsParams, adapter: &Arc, - language_server: &Arc, - event: LanguageServerEvent, - cx: &mut AsyncAppContext, + disk_based_diagnostics_progress_token: Option<&str>, + cx: &mut ModelContext, ) { - let disk_based_diagnostics_progress_token = adapter.disk_based_diagnostics_progress_token(); - match event { - LanguageServerEvent::WorkStart { token } => { - this.update(cx, |this, cx| { - let language_server_status = if let Some(status) = - this.language_server_statuses.get_mut(&language_server_id) - { - status - } else { - return; - }; + adapter.process_diagnostics(&mut params); + if disk_based_diagnostics_progress_token.is_none() { + self.disk_based_diagnostics_started(cx); + self.broadcast_language_server_update( + server_id, + proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( + proto::LspDiskBasedDiagnosticsUpdating {}, + ), + ); + } + self.update_diagnostics(params, adapter.disk_based_diagnostic_sources(), cx) + .log_err(); + if disk_based_diagnostics_progress_token.is_none() { + self.disk_based_diagnostics_finished(cx); + self.broadcast_language_server_update( + server_id, + proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( + proto::LspDiskBasedDiagnosticsUpdated {}, + ), + ); + } + } + + fn on_lsp_progress( + &mut self, + progress: lsp::ProgressParams, + server_id: usize, + disk_based_diagnostics_progress_token: Option<&str>, + cx: &mut ModelContext, + ) { + let token = match progress.token { + lsp::NumberOrString::String(token) => token, + lsp::NumberOrString::Number(token) => { + log::info!("skipping numeric progress token {}", token); + return; + } + }; + + match progress.value { + lsp::ProgressParamsValue::WorkDone(progress) => match progress { + lsp::WorkDoneProgress::Begin(_) => { + let language_server_status = + if let Some(status) = self.language_server_statuses.get_mut(&server_id) { + status + } else { + return; + }; if Some(token.as_str()) == disk_based_diagnostics_progress_token { language_server_status.pending_diagnostic_updates += 1; if language_server_status.pending_diagnostic_updates == 1 { - this.disk_based_diagnostics_started(cx); - this.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( - proto::LspDiskBasedDiagnosticsUpdating {}, - ), - ); + self.disk_based_diagnostics_started(cx); + self.broadcast_language_server_update( + server_id, + proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( + proto::LspDiskBasedDiagnosticsUpdating {}, + ), + ); } } else { - this.on_lsp_work_start(language_server_id, token.clone(), cx); - this.broadcast_language_server_update( - language_server_id, + self.on_lsp_work_start(server_id, token.clone(), cx); + self.broadcast_language_server_update( + server_id, proto::update_language_server::Variant::WorkStart( proto::LspWorkStart { token }, ), ); } - }); - } - LanguageServerEvent::WorkProgress { token, progress } => { - this.update(cx, |this, cx| { + } + lsp::WorkDoneProgress::Report(report) => { if Some(token.as_str()) != disk_based_diagnostics_progress_token { - this.on_lsp_work_progress( - language_server_id, + self.on_lsp_work_progress( + server_id, token.clone(), - progress.clone(), + LanguageServerProgress { + message: report.message.clone(), + percentage: report.percentage.map(|p| p as usize), + last_update_at: Instant::now(), + }, cx, ); - this.broadcast_language_server_update( - language_server_id, + self.broadcast_language_server_update( + server_id, proto::update_language_server::Variant::WorkProgress( proto::LspWorkProgress { token, - message: progress.message, - percentage: progress.percentage.map(|p| p as u32), + message: report.message, + percentage: report.percentage.map(|p| p as u32), }, ), ); } - }); - } - LanguageServerEvent::WorkEnd { token } => { - this.update(cx, |this, cx| { + } + lsp::WorkDoneProgress::End(_) => { if Some(token.as_str()) == disk_based_diagnostics_progress_token { let language_server_status = if let Some(status) = - this.language_server_statuses.get_mut(&language_server_id) + self.language_server_statuses.get_mut(&server_id) { status } else { @@ -1692,69 +1672,25 @@ impl Project { language_server_status.pending_diagnostic_updates -= 1; if language_server_status.pending_diagnostic_updates == 0 { - this.disk_based_diagnostics_finished(cx); - this.broadcast_language_server_update( - language_server_id, + self.disk_based_diagnostics_finished(cx); + self.broadcast_language_server_update( + server_id, proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( proto::LspDiskBasedDiagnosticsUpdated {}, ), ); } } else { - this.on_lsp_work_end(language_server_id, token.clone(), cx); - this.broadcast_language_server_update( - language_server_id, + self.on_lsp_work_end(server_id, token.clone(), cx); + self.broadcast_language_server_update( + server_id, proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token, }), ); } - }); - } - LanguageServerEvent::DiagnosticsUpdate(mut params) => { - this.update(cx, |this, cx| { - adapter.process_diagnostics(&mut params); - - if disk_based_diagnostics_progress_token.is_none() { - this.disk_based_diagnostics_started(cx); - this.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( - proto::LspDiskBasedDiagnosticsUpdating {}, - ), - ); - } - this.update_diagnostics(params, adapter.disk_based_diagnostic_sources(), cx) - .log_err(); - if disk_based_diagnostics_progress_token.is_none() { - this.disk_based_diagnostics_finished(cx); - this.broadcast_language_server_update( - language_server_id, - proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated( - proto::LspDiskBasedDiagnosticsUpdated {}, - ), - ); - } - }); - } - LanguageServerEvent::WorkspaceEdit(params) => { - let transaction = Self::deserialize_workspace_edit( - this.clone(), - params.edit, - true, - adapter.clone(), - language_server.clone(), - cx, - ) - .await - .log_err(); - this.update(cx, |this, _| { - if let Some(transaction) = transaction { - this.last_workspace_edits_by_language_server - .insert(language_server_id, transaction); - } - }); - } + } + }, } } @@ -1802,6 +1738,40 @@ impl Project { } } + async fn on_lsp_workspace_edit( + this: WeakModelHandle, + params: lsp::ApplyWorkspaceEditParams, + server_id: usize, + adapter: Arc, + language_server: Arc, + mut cx: AsyncAppContext, + ) -> Result { + let this = this + .upgrade(&cx) + .ok_or_else(|| anyhow!("project project closed"))?; + let transaction = Self::deserialize_workspace_edit( + this.clone(), + params.edit, + true, + adapter.clone(), + language_server.clone(), + &mut cx, + ) + .await + .log_err(); + this.update(&mut cx, |this, _| { + if let Some(transaction) = transaction { + this.last_workspace_edits_by_language_server + .insert(server_id, transaction); + } + }); + Ok(lsp::ApplyWorkspaceEditResponse { + applied: true, + failed_change: None, + failure_reason: None, + }) + } + fn broadcast_language_server_update( &self, language_server_id: usize, @@ -2746,6 +2716,10 @@ impl Project { ) .await } else if let Some(command) = action.lsp_action.command { + this.update(&mut cx, |this, _| { + this.last_workspace_edits_by_language_server + .remove(&lang_server.server_id()); + }); lang_server .request::(lsp::ExecuteCommandParams { command: command.command, @@ -6071,7 +6045,7 @@ mod tests { } } - #[gpui::test] + #[gpui::test(iterations = 100)] async fn test_apply_code_action(cx: &mut gpui::TestAppContext) { let mut language = Language::new( LanguageConfig { From fe8e06e781b312b3a7771b2564f9c8723a9de3c1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 12:07:41 -0700 Subject: [PATCH 25/68] Fix clipping when using label-only completions --- crates/project/src/project.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index a8311ccf3b144589925ab966fbeaef10cb36122e..d82629ab67eacb93be8940c703bd451e600a47a9 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2373,13 +2373,6 @@ impl Project { }; cx.spawn(|_, cx| async move { - let clipped_position = source_buffer_handle - .read_with(&cx, |this, _| this.clip_point_utf16(position, Bias::Left)); - if clipped_position != position { - log::info!("Completion position out of date"); - return Ok(Default::default()); - } - let completions = lang_server .request::(lsp::CompletionParams { text_document_position: lsp::TextDocumentPositionParams::new( @@ -2412,10 +2405,21 @@ impl Project { Some(lsp::CompletionTextEdit::Edit(edit)) => { (range_from_lsp(edit.range), edit.new_text.clone()) } - None => ( - this.common_prefix_at(position, &lsp_completion.label), - lsp_completion.label.clone(), - ), + None => { + let clipped_position = + this.clip_point_utf16(position, Bias::Left); + if position != clipped_position { + log::info!("completion out of expected range"); + return None; + } + ( + this.common_prefix_at( + clipped_position, + &lsp_completion.label, + ), + lsp_completion.label.clone(), + ) + } Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { log::info!("unsupported insert/replace completion"); return None; From 6f28033efe8194699da795dfabd824d5c97a65a9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 13:00:06 -0700 Subject: [PATCH 26/68] Add explanatory comments in unit test for code actions w/ commands --- crates/project/src/project.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index d82629ab67eacb93be8940c703bd451e600a47a9..30865b9d5afe118bf96283ff1c1b7ba1871e32e5 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -6049,8 +6049,8 @@ mod tests { } } - #[gpui::test(iterations = 100)] - async fn test_apply_code_action(cx: &mut gpui::TestAppContext) { + #[gpui::test(iterations = 10)] + async fn test_apply_code_actions_with_commands(cx: &mut gpui::TestAppContext) { let mut language = Language::new( LanguageConfig { name: "TypeScript".into(), @@ -6090,6 +6090,7 @@ mod tests { let fake_server = fake_language_servers.next().await.unwrap(); + // Language server returns code actions that contain commands, and not edits. let actions = project.update(cx, |project, cx| project.code_actions(&buffer, 0..0, cx)); fake_server .handle_request::(|_, _| async move { @@ -6116,9 +6117,15 @@ mod tests { let apply = project.update(cx, |project, cx| { project.apply_code_action(buffer.clone(), action, true, cx) }); + + // Resolving the code action does not populate its edits. In absence of + // edits, we must execute the given command. fake_server.handle_request::( |action, _| async move { Ok(action) }, ); + + // While executing the command, the language server sends the editor + // a `workspaceEdit` request. fake_server .handle_request::({ let fake = fake_server.clone(); @@ -6158,6 +6165,8 @@ mod tests { .next() .await; + // Applying the code action returns a project transaction containing the edits + // sent by the language server in its `workspaceEdit` request. let transaction = apply.await.unwrap(); assert!(transaction.0.contains_key(&buffer)); buffer.update(cx, |buffer, cx| { From 5090e6f146de4bbd00f6a57f1d8f3fd37286e3eb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 14:49:36 -0700 Subject: [PATCH 27/68] Fix common_prefix_at panic when needle contains multibyte chars Also, make the prefix matching case-insensitive, since this is the typical behavior with autocomplete. --- crates/text/src/tests.rs | 50 ++++++++++++++++++++++++++++++++++------ crates/text/src/text.rs | 34 +++++++++++---------------- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs index 54e802b52194721484761e95507de9af516b0512..9348ff0ba6a26e6510840b39587b5558d92f297d 100644 --- a/crates/text/src/tests.rs +++ b/crates/text/src/tests.rs @@ -7,7 +7,6 @@ use std::{ iter::Iterator, time::{Duration, Instant}, }; -use util::test::marked_text_ranges; #[cfg(test)] #[ctor::ctor] @@ -167,14 +166,51 @@ fn test_line_len() { #[test] fn test_common_prefix_at_positionn() { - let (text, ranges) = marked_text_ranges("a = [bcd]"); + let text = "a = str; b = δα"; let buffer = Buffer::new(0, 0, History::new(text.into())); - let snapshot = &buffer.snapshot(); - let expected_range = ranges[0].to_offset(&snapshot); + + let offset1 = offset_after(text, "str"); + let offset2 = offset_after(text, "δα"); + + // the preceding word is a prefix of the suggestion + assert_eq!( + buffer.common_prefix_at(offset1, "string"), + range_of(text, "str"), + ); + // a suffix of the preceding word is a prefix of the suggestion + assert_eq!( + buffer.common_prefix_at(offset1, "tree"), + range_of(text, "tr"), + ); + // the preceding word is a substring of the suggestion, but not a prefix + assert_eq!( + buffer.common_prefix_at(offset1, "astro"), + empty_range_after(text, "str"), + ); + + // prefix matching is case insenstive. assert_eq!( - buffer.common_prefix_at(expected_range.end, "bcdef"), - expected_range - ) + buffer.common_prefix_at(offset1, "Strαngε"), + range_of(text, "str"), + ); + assert_eq!( + buffer.common_prefix_at(offset2, "ΔΑΜΝ"), + range_of(text, "δα"), + ); + + fn offset_after(text: &str, part: &str) -> usize { + text.find(part).unwrap() + part.len() + } + + fn empty_range_after(text: &str, part: &str) -> Range { + let offset = offset_after(text, part); + offset..offset + } + + fn range_of(text: &str, part: &str) -> Range { + let start = text.find(part).unwrap(); + start..start + part.len() + } } #[test] diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index ea0af9d21f5394409dbeda9d5d22f4964110ebf5..1c351079a7ddae872652707b106abea01c8f70fd 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1510,31 +1510,25 @@ impl BufferSnapshot { pub fn common_prefix_at(&self, position: T, needle: &str) -> Range where - T: Clone + ToOffset + FromAnchor, + T: ToOffset + TextDimension, { - let position_offset = position.to_offset(self); - // Get byte indices and char counts for every character in needle in reverse order - let char_indices = needle + let offset = position.to_offset(self); + let common_prefix_len = needle .char_indices() .map(|(index, _)| index) - .chain(std::iter::once(needle.len())) - .enumerate() - // Don't test any prefixes that are bigger than the requested position - .take_while(|(_, prefix_length)| *prefix_length <= position_offset); - - let start = char_indices - // Compute the prefix string and prefix start location - .map(move |(byte_position, char_length)| { - (position_offset - char_length, &needle[..byte_position]) + .chain([needle.len()]) + .take_while(|&len| len <= offset) + .filter(|&len| { + let left = self + .chars_for_range(offset - len..offset) + .flat_map(|c| char::to_lowercase(c)); + let right = needle[..len].chars().flat_map(|c| char::to_lowercase(c)); + left.eq(right) }) - // Only take strings when the prefix is contained at the expected prefix position - .filter(|(prefix_offset, prefix)| self.contains_str_at(prefix_offset, prefix)) - // Convert offset to T - .map(|(prefix_offset, _)| T::from_anchor(&self.anchor_before(prefix_offset), self)) .last() - // If no prefix matches, return the passed in position to create an empty range - .unwrap_or(position.clone()); - + .unwrap_or(0); + let start_offset = offset - common_prefix_len; + let start = self.text_summary_for_range(0..start_offset); start..position } From 7ad862673d748f669c2170b36df937a6c42bbf85 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 15:05:03 -0700 Subject: [PATCH 28/68] Add basic syntax highlight colors for typescript completions --- crates/zed/src/languages/typescript.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index d08da116a544478693ceeea3a397868b653613cd..aca8cdef52df87e5e1d566726f75901f834543c1 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -115,6 +115,29 @@ impl LspAdapter for TypeScriptLspAdapter { fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} + fn label_for_completion( + &self, + item: &lsp::CompletionItem, + language: &language::Language, + ) -> Option { + use lsp::CompletionItemKind as Kind; + let len = item.label.len(); + let grammar = language.grammar()?; + let highlight_id = match item.kind? { + Kind::CLASS | Kind::INTERFACE => grammar.highlight_id_for_name("type"), + Kind::CONSTRUCTOR => grammar.highlight_id_for_name("type"), + Kind::CONSTANT => grammar.highlight_id_for_name("constant"), + Kind::FUNCTION | Kind::METHOD => grammar.highlight_id_for_name("function"), + Kind::PROPERTY | Kind::FIELD => grammar.highlight_id_for_name("property"), + _ => None, + }?; + Some(language::CodeLabel { + text: item.label.clone(), + runs: vec![(0..len, highlight_id)], + filter_range: 0..len, + }) + } + fn initialization_options(&self) -> Option { Some(json!({ "provideFormatter": true From c4d3bbf18448e3488eb75b03a23cf4cc3ad30220 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Apr 2022 15:17:30 -0700 Subject: [PATCH 29/68] Bump protocol version --- crates/rpc/src/rpc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/src/rpc.rs b/crates/rpc/src/rpc.rs index cfe780d5118c764a829cf047d288bc1e7a0b590e..9ee18faae2543b93e194f0e3c2a4fbe9e6604a84 100644 --- a/crates/rpc/src/rpc.rs +++ b/crates/rpc/src/rpc.rs @@ -5,4 +5,4 @@ pub mod proto; pub use conn::Connection; pub use peer::*; -pub const PROTOCOL_VERSION: u32 = 12; +pub const PROTOCOL_VERSION: u32 = 13; From 92256292081c9b18c0fde68dd0a0f46ca90dd807 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 15:51:59 +0200 Subject: [PATCH 30/68] Re-render breadcrumbs on save or when the editor title changes --- crates/breadcrumbs/src/breadcrumbs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index ce32fb22723833fdf86c5ec2c49c155f34368b2a..7085712f8c1f5299e1c4c68b40c09b0955a0cd1e 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -99,7 +99,9 @@ impl ToolbarItemView for Breadcrumbs { if let Some(editor) = item.act_as::(cx) { self.subscriptions .push(cx.subscribe(&editor, |_, _, event, cx| match event { - editor::Event::BufferEdited => cx.notify(), + editor::Event::BufferEdited + | editor::Event::TitleChanged + | editor::Event::Saved => cx.notify(), editor::Event::SelectionsChanged { local } if *local => cx.notify(), _ => {} })); From c39de1f9dc1d59e27be549e62fd99ffe56ecfb0f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:10:10 +0200 Subject: [PATCH 31/68] Show full path for file worktrees or when there is more than 1 worktree --- Cargo.lock | 1 + crates/breadcrumbs/Cargo.toml | 1 + crates/breadcrumbs/src/breadcrumbs.rs | 35 +++++++++++++++++---------- crates/editor/src/multi_buffer.rs | 11 +++++++-- crates/zed/src/zed.rs | 27 ++++++++++++--------- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 276fbf1525ff8d21f678e1b47a6ca7abf8abc697..2c64dd0ba78d68af43898a92304da3f23322c611 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -727,6 +727,7 @@ dependencies = [ "editor", "gpui", "language", + "project", "search", "theme", "workspace", diff --git a/crates/breadcrumbs/Cargo.toml b/crates/breadcrumbs/Cargo.toml index 2e74fd2090dedaf165c15e950bfe113e8d9c392b..7dbafdb3be560805d18df4fe47a4c0b7c605b95a 100644 --- a/crates/breadcrumbs/Cargo.toml +++ b/crates/breadcrumbs/Cargo.toml @@ -12,6 +12,7 @@ collections = { path = "../collections" } editor = { path = "../editor" } gpui = { path = "../gpui" } language = { path = "../language" } +project = { path = "../project" } search = { path = "../search" } theme = { path = "../theme" } workspace = { path = "../workspace" } diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 7085712f8c1f5299e1c4c68b40c09b0955a0cd1e..0f8ac9274e3bf69c5baa972799df9c8743d9564e 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -1,10 +1,11 @@ use editor::{Anchor, Editor}; use gpui::{ - elements::*, AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle, + elements::*, AppContext, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext, + ViewHandle, }; -use language::{BufferSnapshot, OutlineItem}; +use language::{Buffer, OutlineItem}; +use project::Project; use search::ProjectSearchView; -use std::borrow::Cow; use theme::SyntaxTheme; use workspace::{ItemHandle, Settings, ToolbarItemLocation, ToolbarItemView}; @@ -13,14 +14,16 @@ pub enum Event { } pub struct Breadcrumbs { + project: ModelHandle, editor: Option>, project_search: Option>, subscriptions: Vec, } impl Breadcrumbs { - pub fn new() -> Self { + pub fn new(project: ModelHandle) -> Self { Self { + project, editor: Default::default(), subscriptions: Default::default(), project_search: Default::default(), @@ -31,14 +34,14 @@ impl Breadcrumbs { &self, theme: &SyntaxTheme, cx: &AppContext, - ) -> Option<(BufferSnapshot, Vec>)> { + ) -> Option<(ModelHandle, Vec>)> { let editor = self.editor.as_ref()?.read(cx); let cursor = editor.newest_anchor_selection().head(); - let (buffer, symbols) = editor - .buffer() - .read(cx) + let multibuffer = &editor.buffer().read(cx); + let (buffer_id, symbols) = multibuffer .read(cx) .symbols_containing(cursor, Some(theme))?; + let buffer = multibuffer.buffer(buffer_id)?; Some((buffer, symbols)) } } @@ -60,15 +63,21 @@ impl View for Breadcrumbs { } else { return Empty::new().boxed(); }; - - let filename = if let Some(path) = buffer.path() { - path.to_string_lossy() + let buffer = buffer.read(cx); + let filename = if let Some(file) = buffer.file() { + if file.path().file_name().is_none() + || self.project.read(cx).visible_worktrees(cx).count() > 1 + { + file.full_path(cx).to_string_lossy().to_string() + } else { + file.path().to_string_lossy().to_string() + } } else { - Cow::Borrowed("untitled") + "untitled".to_string() }; Flex::row() - .with_child(Label::new(filename.to_string(), theme.breadcrumbs.text.clone()).boxed()) + .with_child(Label::new(filename, theme.breadcrumbs.text.clone()).boxed()) .with_children(symbols.into_iter().flat_map(|symbol| { [ Label::new(" 〉 ".to_string(), theme.breadcrumbs.text.clone()).boxed(), diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index ad3fc3202d94cfeef9f6ace31ccac8068b0c9b10..c07df895c995eda51d44da0221a30bf5118b5e39 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -1001,6 +1001,13 @@ impl MultiBuffer { .collect() } + pub fn buffer(&self, buffer_id: usize) -> Option> { + self.buffers + .borrow() + .get(&buffer_id) + .map(|state| state.buffer.clone()) + } + pub fn save(&mut self, cx: &mut ModelContext) -> Task> { let mut save_tasks = Vec::new(); for BufferState { buffer, .. } in self.buffers.borrow().values() { @@ -2268,12 +2275,12 @@ impl MultiBufferSnapshot { &self, offset: T, theme: Option<&SyntaxTheme>, - ) -> Option<(BufferSnapshot, Vec>)> { + ) -> Option<(usize, Vec>)> { let anchor = self.anchor_before(offset); let excerpt_id = anchor.excerpt_id(); let excerpt = self.excerpt(excerpt_id)?; Some(( - excerpt.buffer.clone(), + excerpt.buffer_id, excerpt .buffer .symbols_containing(anchor.text_anchor, theme) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 7b54b3df9a2d07ee9e5cc6963536cc091f713792..aec0bc533e4a1842789b813c4fc060eaa334e165 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -106,18 +106,21 @@ pub fn build_workspace( app_state: &Arc, cx: &mut ViewContext, ) -> Workspace { - cx.subscribe(&cx.handle(), |_, _, event, cx| { - let workspace::Event::PaneAdded(pane) = event; - pane.update(cx, |pane, cx| { - pane.toolbar().update(cx, |toolbar, cx| { - let breadcrumbs = cx.add_view(|_| Breadcrumbs::new()); - toolbar.add_item(breadcrumbs, cx); - let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); - toolbar.add_item(buffer_search_bar, cx); - let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); - toolbar.add_item(project_search_bar, cx); - }) - }); + cx.subscribe(&cx.handle(), { + let project = project.clone(); + move |_, _, event, cx| { + let workspace::Event::PaneAdded(pane) = event; + pane.update(cx, |pane, cx| { + pane.toolbar().update(cx, |toolbar, cx| { + let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(project.clone())); + toolbar.add_item(breadcrumbs, cx); + let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); + toolbar.add_item(buffer_search_bar, cx); + let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); + toolbar.add_item(project_search_bar, cx); + }) + }); + } }) .detach(); From d0a17f8c2cda6ffc8eeee68460a650c83a8e76e5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:16:47 +0200 Subject: [PATCH 32/68] Update toolbar and automatically unfollow when navigating back and forth --- crates/workspace/src/pane.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 33df9fd4c79285919330510a383befb94b6e5284..8dfe0f49a2abe72abc1a18455e028a135321bb6b 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -207,13 +207,16 @@ impl Pane { let prev_active_index = mem::replace(&mut pane.active_item_index, index); pane.focus_active_item(cx); + pane.update_toolbar(cx); + cx.emit(Event::ActivateItem { local: true }); + cx.notify(); + let mut navigated = prev_active_index != pane.active_item_index; if let Some(data) = entry.data { navigated |= pane.active_item()?.navigate(data, cx); } if navigated { - cx.notify(); break None; } } From b0b54365c79e7431a735c8132a93647df3fcf57a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 2 Apr 2022 16:19:15 +0200 Subject: [PATCH 33/68] Re-render breadcrumbs when buffer has been reparsed --- crates/breadcrumbs/src/breadcrumbs.rs | 3 ++- crates/editor/src/editor.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index 0f8ac9274e3bf69c5baa972799df9c8743d9564e..59c8b08b685270576967492f3f0c87d659a5799b 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -110,7 +110,8 @@ impl ToolbarItemView for Breadcrumbs { .push(cx.subscribe(&editor, |_, _, event, cx| match event { editor::Event::BufferEdited | editor::Event::TitleChanged - | editor::Event::Saved => cx.notify(), + | editor::Event::Saved + | editor::Event::Reparsed => cx.notify(), editor::Event::SelectionsChanged { local } if *local => cx.notify(), _ => {} })); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 1135c9b260367a563add678c6a73a46b2d6d561e..8a35e4b3d21faaace8275e9a4cd091d1a6124840 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -5860,6 +5860,7 @@ impl Editor { self.refresh_code_actions(cx); cx.emit(Event::BufferEdited); } + language::Event::Reparsed => cx.emit(Event::Reparsed), language::Event::Dirtied => cx.emit(Event::Dirtied), language::Event::Saved => cx.emit(Event::Saved), language::Event::FileHandleChanged => cx.emit(Event::TitleChanged), @@ -5987,6 +5988,7 @@ pub enum Event { Activate, BufferEdited, Edited, + Reparsed, Blurred, Dirtied, Saved, From 80b599c4ef3ba126a508527df64cd51cfa80171f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sun, 3 Apr 2022 12:43:33 +0200 Subject: [PATCH 34/68] Prompt to save untitled buffers when closing them while they are dirty --- crates/workspace/src/pane.rs | 168 ++++++++++++++++++++++++++--------- 1 file changed, 126 insertions(+), 42 deletions(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 33df9fd4c79285919330510a383befb94b6e5284..afafe480c02b5cd1443e561425d327a98287bdb8 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -12,7 +12,7 @@ use gpui::{ View, ViewContext, ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; -use std::{any::Any, cell::RefCell, cmp, mem, rc::Rc}; +use std::{any::Any, cell::RefCell, cmp, mem, path::Path, rc::Rc}; use util::ResultExt; action!(Split, SplitDirection); @@ -443,14 +443,14 @@ impl Pane { }) { let item = this.read_with(&cx, |this, _| this.items[item_to_close_ix].boxed_clone()); - if cx.read(|cx| item.can_save(cx)) { - if cx.read(|cx| item.has_conflict(cx)) { + if cx.read(|cx| item.is_dirty(cx)) { + if cx.read(|cx| item.can_save(cx)) { let mut answer = this.update(&mut cx, |this, cx| { this.activate_item(item_to_close_ix, true, cx); cx.prompt( PromptLevel::Warning, - CONFLICT_MESSAGE, - &["Overwrite", "Discard", "Cancel"], + DIRTY_MESSAGE, + &["Save", "Don't Save", "Cancel"], ) }); @@ -465,19 +465,10 @@ impl Pane { break; } } - Some(1) => { - if cx - .update(|cx| item.reload(project.clone(), cx)) - .await - .log_err() - .is_none() - { - break; - } - } + Some(1) => {} _ => break, } - } else if cx.read(|cx| item.is_dirty(cx)) { + } else if cx.read(|cx| item.can_save_as(cx)) { let mut answer = this.update(&mut cx, |this, cx| { this.activate_item(item_to_close_ix, true, cx); cx.prompt( @@ -489,12 +480,25 @@ impl Pane { match answer.next().await { Some(0) => { - if cx - .update(|cx| item.save(project.clone(), cx)) - .await - .log_err() - .is_none() - { + let start_abs_path = project + .read_with(&cx, |project, cx| { + let worktree = project.visible_worktrees(cx).next()?; + Some(worktree.read(cx).as_local()?.abs_path().to_path_buf()) + }) + .unwrap_or(Path::new("").into()); + + let mut abs_path = + cx.update(|cx| cx.prompt_for_new_path(&start_abs_path)); + if let Some(abs_path) = abs_path.next().await.flatten() { + if cx + .update(|cx| item.save_as(project.clone(), abs_path, cx)) + .await + .log_err() + .is_none() + { + break; + } + } else { break; } } @@ -502,6 +506,39 @@ impl Pane { _ => break, } } + } else if cx.read(|cx| item.has_conflict(cx) && item.can_save(cx)) { + let mut answer = this.update(&mut cx, |this, cx| { + this.activate_item(item_to_close_ix, true, cx); + cx.prompt( + PromptLevel::Warning, + CONFLICT_MESSAGE, + &["Overwrite", "Discard", "Cancel"], + ) + }); + + match answer.next().await { + Some(0) => { + if cx + .update(|cx| item.save(project.clone(), cx)) + .await + .log_err() + .is_none() + { + break; + } + } + Some(1) => { + if cx + .update(|cx| item.reload(project.clone(), cx)) + .await + .log_err() + .is_none() + { + break; + } + } + _ => break, + } } this.update(&mut cx, |this, cx| { @@ -532,6 +569,7 @@ impl Pane { } else { this.focus_active_item(cx); this.activate(cx); + cx.emit(Event::ActivateItem { local: true }); } this.update_toolbar(cx); cx.notify(); @@ -832,32 +870,58 @@ mod tests { let params = cx.update(WorkspaceParams::test); let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); - let item1 = cx.add_view(window_id, |_| TestItem::new(false, true)); - let item2 = cx.add_view(window_id, |_| TestItem::new(true, true)); - let item3 = cx.add_view(window_id, |_| TestItem::new(false, true)); - let item4 = cx.add_view(window_id, |_| TestItem::new(true, false)); + let item1 = cx.add_view(window_id, |_| { + let mut item = TestItem::new(); + item.has_conflict = true; + item + }); + let item2 = cx.add_view(window_id, |_| { + let mut item = TestItem::new(); + item.is_dirty = true; + item.has_conflict = true; + item + }); + let item3 = cx.add_view(window_id, |_| { + let mut item = TestItem::new(); + item.has_conflict = true; + item + }); + let item4 = cx.add_view(window_id, |_| { + let mut item = TestItem::new(); + item.is_dirty = true; + item + }); + let item5 = cx.add_view(window_id, |_| { + let mut item = TestItem::new(); + item.is_dirty = true; + item.can_save = false; + item + }); let pane = workspace.update(cx, |workspace, cx| { workspace.add_item(Box::new(item1.clone()), cx); + workspace.add_item(Box::new(item2.clone()), cx); workspace.add_item(Box::new(item3.clone()), cx); workspace.add_item(Box::new(item4.clone()), cx); - workspace.add_item(Box::new(item2.clone()), cx); - assert_eq!(workspace.active_item(cx).unwrap().id(), item2.id()); - + workspace.add_item(Box::new(item5.clone()), cx); workspace.active_pane().clone() }); let close_items = pane.update(cx, |pane, cx| { + pane.activate_item(1, true, cx); + assert_eq!(pane.active_item().unwrap().id(), item2.id()); + let item1_id = item1.id(); let item3_id = item3.id(); let item4_id = item4.id(); + let item5_id = item5.id(); pane.close_items(cx, move |id| { - id == item1_id || id == item3_id || id == item4_id + [item1_id, item3_id, item4_id, item5_id].contains(&id) }) }); cx.foreground().run_until_parked(); pane.read_with(cx, |pane, _| { - assert_eq!(pane.items.len(), 4); + assert_eq!(pane.items.len(), 5); assert_eq!(pane.active_item().unwrap().id(), item1.id()); }); @@ -865,8 +929,9 @@ mod tests { cx.foreground().run_until_parked(); pane.read_with(cx, |pane, cx| { assert_eq!(item1.read(cx).save_count, 1); + assert_eq!(item1.read(cx).save_as_count, 0); assert_eq!(item1.read(cx).reload_count, 0); - assert_eq!(pane.items.len(), 3); + assert_eq!(pane.items.len(), 4); assert_eq!(pane.active_item().unwrap().id(), item3.id()); }); @@ -874,35 +939,53 @@ mod tests { cx.foreground().run_until_parked(); pane.read_with(cx, |pane, cx| { assert_eq!(item3.read(cx).save_count, 0); + assert_eq!(item3.read(cx).save_as_count, 0); assert_eq!(item3.read(cx).reload_count, 1); - assert_eq!(pane.items.len(), 2); + assert_eq!(pane.items.len(), 3); assert_eq!(pane.active_item().unwrap().id(), item4.id()); }); cx.simulate_prompt_answer(window_id, 0); - close_items.await; + cx.foreground().run_until_parked(); pane.read_with(cx, |pane, cx| { assert_eq!(item4.read(cx).save_count, 1); + assert_eq!(item4.read(cx).save_as_count, 0); assert_eq!(item4.read(cx).reload_count, 0); + assert_eq!(pane.items.len(), 2); + assert_eq!(pane.active_item().unwrap().id(), item5.id()); + }); + + cx.simulate_prompt_answer(window_id, 0); + cx.foreground().run_until_parked(); + cx.simulate_new_path_selection(|_| Some(Default::default())); + close_items.await; + pane.read_with(cx, |pane, cx| { + assert_eq!(item5.read(cx).save_count, 0); + assert_eq!(item5.read(cx).save_as_count, 1); + assert_eq!(item5.read(cx).reload_count, 0); assert_eq!(pane.items.len(), 1); assert_eq!(pane.active_item().unwrap().id(), item2.id()); }); } struct TestItem { - is_dirty: bool, - has_conflict: bool, save_count: usize, + save_as_count: usize, reload_count: usize, + is_dirty: bool, + has_conflict: bool, + can_save: bool, } impl TestItem { - fn new(is_dirty: bool, has_conflict: bool) -> Self { + fn new() -> Self { Self { save_count: 0, + save_as_count: 0, reload_count: 0, - is_dirty, - has_conflict, + is_dirty: false, + has_conflict: false, + can_save: true, } } } @@ -945,7 +1028,7 @@ mod tests { } fn can_save(&self, _: &AppContext) -> bool { - true + self.can_save } fn save( @@ -958,7 +1041,7 @@ mod tests { } fn can_save_as(&self, _: &AppContext) -> bool { - false + true } fn save_as( @@ -967,7 +1050,8 @@ mod tests { _: std::path::PathBuf, _: &mut ViewContext, ) -> Task> { - unreachable!() + self.save_as_count += 1; + Task::ready(Ok(())) } fn reload( From 089b0e8e0f195d95c04e47fd33f630a568a0bfb1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sun, 3 Apr 2022 13:00:39 +0200 Subject: [PATCH 35/68] Remove duplicate activation logic when removing items from pane --- crates/workspace/src/pane.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index afafe480c02b5cd1443e561425d327a98287bdb8..f8d145ea9a03d3a5c88ad703f96d0b16401d5f31 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -543,15 +543,23 @@ impl Pane { this.update(&mut cx, |this, cx| { if let Some(item_ix) = this.items.iter().position(|i| i.id() == item.id()) { - this.items.remove(item_ix); if item_ix == this.active_item_index { + if item_ix + 1 < this.items.len() { + this.activate_next_item(cx); + } else if item_ix > 0 { + this.activate_prev_item(cx); + } + } + + let item = this.items.remove(item_ix); + if this.items.is_empty() { item.deactivated(cx); + cx.emit(Event::Remove); } + if item_ix < this.active_item_index { this.active_item_index -= 1; } - this.active_item_index = - cmp::min(this.active_item_index, this.items.len().saturating_sub(1)); let mut nav_history = this.nav_history.borrow_mut(); if let Some(path) = item.project_path(cx) { @@ -563,17 +571,7 @@ impl Pane { }); } - this.update(&mut cx, |this, cx| { - if this.items.is_empty() { - cx.emit(Event::Remove); - } else { - this.focus_active_item(cx); - this.activate(cx); - cx.emit(Event::ActivateItem { local: true }); - } - this.update_toolbar(cx); - cx.notify(); - }) + this.update(&mut cx, |_, cx| cx.notify()); }) } From dee416bdbe5abfa381a8e5bca7202abf4a3445a9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 4 Apr 2022 11:13:35 +0200 Subject: [PATCH 36/68] Avoid text insertion when holding down the `fn` key --- crates/gpui/src/platform/mac/event.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 33f9f22e116b0b2005a0e79947de345dc69d0dcf..7170bd2fd598d81301a3d10342f93c24040301d9 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -30,6 +30,7 @@ impl Event { let alt = modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask); let shift = modifiers.contains(NSEventModifierFlags::NSShiftKeyMask); let cmd = modifiers.contains(NSEventModifierFlags::NSCommandKeyMask); + let function = modifiers.contains(NSEventModifierFlags::NSFunctionKeyMask); let unmodified_chars = CStr::from_ptr( native_event.charactersIgnoringModifiers().UTF8String() as *mut c_char, @@ -80,7 +81,7 @@ impl Event { NSF12FunctionKey => "f12", _ => { - if !cmd && !ctrl { + if !cmd && !ctrl && !function { input = Some( CStr::from_ptr( native_event.characters().UTF8String() as *mut c_char From 328be473e532e232bea2c0f15373a30f09924ea1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 4 Apr 2022 14:14:21 +0200 Subject: [PATCH 37/68] Rename `sub_mode` to `submode` Co-Authored-By: Nathan Sobo --- crates/vim/src/mode.rs | 6 +++--- crates/vim/src/normal/g_prefix.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/vim/src/mode.rs b/crates/vim/src/mode.rs index 2e5dc4ca2c2cdc8418c6b6d4310b8ae518475e14..f00c14e2e84dbfa0c37ab939fafbb6cade81d511 100644 --- a/crates/vim/src/mode.rs +++ b/crates/vim/src/mode.rs @@ -52,15 +52,15 @@ pub enum NormalState { impl NormalState { pub fn set_context(&self, context: &mut Context) { - let sub_mode = match self { + let submode = match self { Self::GPrefix => Some("g"), _ => None, }; - if let Some(sub_mode) = sub_mode { + if let Some(submode) = submode { context .map - .insert("vim_sub_mode".to_string(), sub_mode.to_string()); + .insert("vim_submode".to_string(), submode.to_string()); } } } diff --git a/crates/vim/src/normal/g_prefix.rs b/crates/vim/src/normal/g_prefix.rs index 82510c0cf9364d884a465865923992e25c395586..5b710892459ae62497e7f9ad49ca623eba407303 100644 --- a/crates/vim/src/normal/g_prefix.rs +++ b/crates/vim/src/normal/g_prefix.rs @@ -6,7 +6,7 @@ use crate::{mode::Mode, SwitchMode, VimState}; action!(MoveToStart); pub fn init(cx: &mut MutableAppContext) { - let context = Some("Editor && vim_mode == normal && vim_sub_mode == g"); + let context = Some("Editor && vim_mode == normal && vim_submode == g"); cx.add_bindings(vec![ Binding::new("g", MoveToStart, context), Binding::new("escape", SwitchMode(Mode::normal()), context), From cbf6d827db5df62acd691643e7b80193a2e7a6e1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 4 Apr 2022 15:09:31 +0200 Subject: [PATCH 38/68] v0.24.0 --- Cargo.lock | 2 +- crates/zed/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c64dd0ba78d68af43898a92304da3f23322c611..c4a7112abd41bc7ee3621f0f4d8fa88b026e852f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5981,7 +5981,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "zed" -version = "0.23.0" +version = "0.24.0" dependencies = [ "anyhow", "async-compression", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 68d23b44f8b7893b13511cef6cf2465219d51431..2e1ef780caf77d6e0ffd0352e60b137ee7a07a71 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] description = "The fast, collaborative code editor." edition = "2021" name = "zed" -version = "0.23.0" +version = "0.24.0" [lib] name = "zed" From 2aebb04a8482e842daf018dfec8c7f0edc9fa6a6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 29 Mar 2022 13:08:00 -0600 Subject: [PATCH 39/68] Start on TypeScript-based styling system Co-Authored-By: Nate Butler <1714999+iamnbutler@users.noreply.github.com> --- .gitignore | 1 + styles/app.ts | 632 +++++++++++++++++++++++++++++++++++++++ styles/components.ts | 62 ++++ styles/core.ts | 38 +++ styles/package-lock.json | 28 ++ styles/package.json | 14 + styles/selector-modal.ts | 59 ++++ styles/theme.ts | 121 ++++++++ 8 files changed, 955 insertions(+) create mode 100644 styles/app.ts create mode 100644 styles/components.ts create mode 100644 styles/core.ts create mode 100644 styles/package-lock.json create mode 100644 styles/package.json create mode 100644 styles/selector-modal.ts create mode 100644 styles/theme.ts diff --git a/.gitignore b/.gitignore index e88434ce4e718285669691175d297842a3b16b33..140053fc2c507f788748b43136b1eaa5c52680da 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /zed.xcworkspace .DS_Store /script/node_modules +/styles/node_modules /crates/server/.env.toml /crates/server/static/styles.css /vendor/bin diff --git a/styles/app.ts b/styles/app.ts new file mode 100644 index 0000000000000000000000000000000000000000..a7ae4348bea1d2e0861d0d4a957cd6eb7a3c7adf --- /dev/null +++ b/styles/app.ts @@ -0,0 +1,632 @@ +import { selectorModal } from "./selector-modal"; +import Theme from "./theme"; + +export default function app(theme: Theme): Object { + return { + selector: selectorModal(theme), + workspace: { + background: "$surface.500", + leaderBorderOpacity: 0.7, + leader_border_width: 2.0, + active_tab: { + background: "$surface.300", + extends: "$workspace.tab", + text: "$text.primary", + border: { + bottom: false, + }, + }, + left_sidebar: { + extends: "$workspace.sidebar", + border: { + color: "$border.primary", + right: true, + width: 1, + }, + }, + pane_divider: { + color: "$border.primary", + width: 1, + }, + right_sidebar: { + extends: "$workspace.sidebar", + border: { + color: "$border.primary", + left: true, + width: 1, + }, + }, + sidebar: { + width: 30, + active_item: { + extends: "$workspace.sidebar.item", + icon_color: "$text.primary.color", + }, + border: { + color: "$border.primary", + right: true, + width: 1, + }, + item: { + height: "$workspace.tab.height", + icon_color: "$text.muted.color", + icon_size: 18, + }, + resize_handle: { + background: "$border.primary", + padding: { + left: 1, + }, + }, + }, + status_bar: { + cursor_position: "$text.muted", + diagnostic_message: "$text.muted", + height: 24, + item_spacing: 8, + lsp_message: "$text.muted", + padding: { + left: 6, + right: 6, + }, + }, + tab: { + height: 34, + icon_close: "$text.muted.color", + icon_close_active: "$text.primary.color", + icon_conflict: "$status.warn", + icon_dirty: "$status.info", + icon_width: 8, + spacing: 10, + text: "$text.muted", + border: { + bottom: true, + color: "$border.primary", + left: true, + overlay: true, + width: 1, + }, + padding: { + left: 12, + right: 12, + }, + }, + titlebar: { + avatar_width: 18, + height: 32, + share_icon_active_color: "$text.primary.color", + share_icon_color: "$text.muted.color", + title: "$text.primary", + avatar: { + corner_radius: 10, + border: { + color: "#00000088", + width: 1, + }, + }, + avatar_ribbon: { + background: "#ff0000", + height: 3, + width: 12, + }, + border: { + bottom: true, + color: "$border.primary", + width: 1, + }, + hovered_sign_in_prompt: { + color: "$text.secondary.color", + extends: "$workspace.titlebar.sign_in_prompt", + }, + offline_icon: { + color: "$text.muted.color", + width: 16, + padding: { + right: 4, + }, + }, + outdated_warning: { + extends: "$text.muted", + size: 13, + }, + sign_in_prompt: { + extends: "$text.muted", + size: 13, + underline: true, + padding: { + right: 8, + }, + }, + }, + toolbar: { + height: 44, + }, + }, + chat_panel: { + extends: "$panel", + channel_name: { + extends: "$text.primary", + weight: "bold", + }, + channel_name_hash: { + text: "$text.muted", + padding: { + right: 8, + }, + }, + channel_select: { + active_item: { + extends: "$chat_panel.channel_select.item", + name: "$text.primary", + }, + header: { + extends: "$chat_panel.channel_select.active_item", + padding: { + bottom: 4, + left: 0, + }, + }, + hovered_active_item: { + extends: "$chat_panel.channel_select.hovered_item", + name: "$text.primary", + }, + hovered_item: { + background: "$state.hover", + corner_radius: 6, + extends: "$chat_panel.channel_select.item", + }, + item: { + name: "$text.secondary", + padding: 4, + hash: { + extends: "$text.muted", + margin: { + right: 8, + }, + }, + }, + menu: { + background: "$surface.500", + corner_radius: 6, + padding: 4, + border: { + color: "$border.primary", + width: 1, + }, + shadow: { + blur: 16, + color: "$shadow.0", + offset: [0, 2], + }, + }, + }, + hovered_sign_in_prompt: { + color: "$text.secondary.color", + extends: "$chat_panel.sign_in_prompt", + }, + input_editor: { + background: "$surface.300", + corner_radius: 6, + placeholder_text: "$text.muted", + selection: "$selection.host", + text: "$text.primary", + border: { + color: "$border.primary", + width: 1, + }, + padding: { + bottom: 7, + left: 8, + right: 8, + top: 7, + }, + }, + message: { + body: "$text.secondary", + timestamp: "$text.muted", + padding: { + bottom: 6, + }, + sender: { + extends: "$text.primary", + weight: "bold", + margin: { + right: 8, + }, + }, + }, + pending_message: { + extends: "$chat_panel.message", + body: { + color: "$text.muted.color", + }, + sender: { + color: "$text.muted.color", + }, + timestamp: { + color: "$text.muted.color", + }, + }, + sign_in_prompt: { + extends: "$text.primary", + underline: true, + }, + }, + contacts_panel: { + extends: "$panel", + host_row_height: 28, + tree_branch_color: "$surface.100", + tree_branch_width: 1, + host_avatar: { + corner_radius: 10, + width: 18, + }, + host_username: { + extends: "$text.primary", + padding: { + left: 8, + }, + }, + hovered_shared_project: { + background: "$state.hover", + corner_radius: 6, + extends: "$contacts_panel.shared_project", + }, + hovered_unshared_project: { + background: "$state.hover", + corner_radius: 6, + extends: "$contacts_panel.unshared_project", + }, + project: { + guest_avatar_spacing: 4, + height: 24, + guest_avatar: { + corner_radius: 8, + width: 14, + }, + name: { + extends: "$text.secondary", + margin: { + right: 6, + }, + }, + padding: { + left: 8, + }, + }, + shared_project: { + extends: "$contacts_panel.project", + name: { + color: "$text.primary.color", + }, + }, + unshared_project: { + extends: "$contacts_panel.project", + }, + }, + editor: { + active_line_background: "$state.active_line", + background: "$surface.300", + code_actions_indicator: "$text.muted.color", + diff_background_deleted: "$state.deleted_line", + diff_background_inserted: "$state.inserted_line", + document_highlight_read_background: "#99999920", + document_highlight_write_background: "#99999916", + error_color: "$status.bad", + guest_selections: "$selection.guests", + gutter_background: "$surface.300", + gutter_padding_factor: 2.5, + highlighted_line_background: "$state.highlighted_line", + line_number: "$text.muted.color", + line_number_active: "$text.primary.color", + rename_fade: 0.6, + selection: "$selection.host", + text_color: "$text.secondary.color", + unnecessary_code_fade: 0.5, + autocomplete: { + background: "$surface.100", + corner_radius: 6, + padding: 6, + border: { + color: "$border.secondary", + width: 2, + }, + hovered_item: { + background: "$state.hover", + extends: "$editor.autocomplete.item", + }, + item: { + corner_radius: 6, + padding: { + bottom: 2, + left: 6, + right: 6, + top: 2, + }, + }, + margin: { + left: -14, + }, + match_highlight: { + color: "$editor.syntax.keyword.color", + weight: "$editor.syntax.keyword.weight", + }, + selected_item: { + background: "$state.selected", + extends: "$editor.autocomplete.item", + }, + }, + diagnostic_header: { + background: "$editor.background", + icon_width_factor: 1.5, + text_scale_factor: 0.857, + border: { + bottom: true, + color: "$border.secondary", + top: true, + width: 1, + }, + code: { + extends: "$text.muted", + size: 14, + margin: { + left: 10, + }, + }, + message: { + highlight_text: { + extends: "$text.primary", + size: 14, + weight: "bold", + }, + text: { + extends: "$text.secondary", + size: 14, + }, + }, + }, + diagnostic_path_header: { + background: "$state.active_line", + text_scale_factor: 0.857, + filename: { + extends: "$text.primary", + size: 14, + }, + path: { + extends: "$text.muted", + size: 14, + margin: { + left: 12, + }, + }, + }, + error_diagnostic: { + text_scale_factor: 0.857, + header: { + border: { + color: "$border.primary", + top: true, + width: 1, + }, + }, + message: { + highlight_text: { + color: "$status.bad", + extends: "$text.secondary", + size: 14, + weight: "bold", + }, + text: { + color: "$status.bad", + extends: "$text.secondary", + size: 14, + }, + }, + }, + hint_diagnostic: { + extends: "$editor.error_diagnostic", + message: { + highlight_text: { + color: "$status.info", + }, + text: { + color: "$status.info", + }, + }, + }, + information_diagnostic: { + extends: "$editor.error_diagnostic", + message: { + highlight_text: { + color: "$status.info", + }, + text: { + color: "$status.info", + }, + }, + }, + invalid_error_diagnostic: { + extends: "$editor.error_diagnostic", + message: { + highlight_text: { + color: "$text.muted.color", + }, + text: { + color: "$text.muted.color", + }, + }, + }, + invalid_hint_diagnostic: { + extends: "$editor.hint_diagnostic", + message: { + highlight_text: { + color: "$text.muted.color", + }, + text: { + color: "$text.muted.color", + }, + }, + }, + invalid_information_diagnostic: { + extends: "$editor.information_diagnostic", + message: { + highlight_text: { + color: "$text.muted.color", + }, + text: { + color: "$text.muted.color", + }, + }, + }, + invalid_warning_diagnostic: { + extends: "$editor.warning_diagnostic", + message: { + highlight_text: { + color: "$text.muted.color", + }, + text: { + color: "$text.muted.color", + }, + }, + }, + warning_diagnostic: { + extends: "$editor.error_diagnostic", + message: { + highlight_text: { + color: "$status.warn", + }, + text: { + color: "$status.warn", + }, + }, + }, + }, + project_diagnostics: { + background: "$surface.300", + tab_icon_spacing: 4, + tab_icon_width: 13, + tab_summary_spacing: 10, + empty_message: { + extends: "$text.primary", + size: 18, + }, + status_bar_item: { + extends: "$text.muted", + margin: { + right: 10, + }, + }, + }, + project_panel: { + extends: "$panel", + entry: { + height: 22, + icon_color: "$text.muted.color", + icon_size: 8, + icon_spacing: 8, + text: "$text.secondary", + }, + hovered_entry: { + background: "$state.hover", + extends: "$project_panel.entry", + }, + hovered_selected_entry: { + extends: "$project_panel.hovered_entry", + text: { + extends: "$text.primary", + }, + }, + padding: { + top: 6, + }, + selected_entry: { + extends: "$project_panel.entry", + text: { + extends: "$text.primary", + }, + }, + }, + search: { + background: "$surface.300", + match_background: "$state.highlighted_line", + tab_icon_spacing: 4, + tab_icon_width: 14, + active_hovered_option_button: { + background: "$surface.100", + extends: "$search.option_button", + }, + active_option_button: { + background: "$surface.100", + extends: "$search.option_button", + }, + editor: { + background: "$surface.500", + corner_radius: 6, + max_width: 400, + placeholder_text: "$text.muted", + selection: "$selection.host", + text: "$text.primary", + border: { + color: "$border.primary", + width: 1, + }, + margin: { + bottom: 5, + left: 5, + right: 5, + top: 5, + }, + padding: { + bottom: 3, + left: 13, + right: 13, + top: 3, + }, + }, + hovered_option_button: { + background: "$surface.100", + extends: "$search.option_button", + }, + invalid_editor: { + extends: "$search.editor", + border: { + color: "$status.bad", + width: 1, + }, + }, + match_index: { + extends: "$text.secondary", + padding: 6, + }, + option_button: { + background: "$surface.300", + corner_radius: 6, + extends: "$text.secondary", + border: { + color: "$border.primary", + width: 1, + }, + margin: { + left: 1, + right: 1, + }, + padding: { + bottom: 1, + left: 6, + right: 6, + top: 1, + }, + }, + option_button_group: { + padding: { + left: 2, + right: 2, + }, + }, + results_status: { + extends: "$text.primary", + size: 18, + }, + }, + }; +} diff --git a/styles/components.ts b/styles/components.ts new file mode 100644 index 0000000000000000000000000000000000000000..226d1d9e374274ce82938f85c1a73d0c669a468c --- /dev/null +++ b/styles/components.ts @@ -0,0 +1,62 @@ +import chroma from "chroma-js"; +import core, { Color } from "./core"; +import Theme, { BackgroundColor, Weight } from "./theme"; + +export function text( + theme: Theme, + fontFamily: keyof typeof core.fontFamily, + color: keyof Theme["textColor"], + properties?: { size?: keyof typeof core["fontSize"]; weight?: Weight } +) { + const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md"; + const size = core.fontSize[sizeKey].value; + + return { + family: core.fontFamily[fontFamily], + color: theme.textColor[color].value, + ...properties, + size, + }; +} + +export function border(theme: Theme, color: keyof Theme["borderColor"]) { + return { + color: theme.borderColor[color].value, + width: 1, + }; +} + +export interface Player { + selection: { + cursor: Color; + selection: Color; + }; +} + +export function player( + theme: Theme, + playerNumber: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 +): Player { + return { + selection: { + cursor: theme.player[playerNumber].cursorColor.value, + selection: theme.player[playerNumber].selectionColor.value, + }, + }; +} + +export function backgroundColor( + theme: Theme, + name: keyof Theme["backgroundColor"], + state?: keyof BackgroundColor +): Color { + return theme.backgroundColor[name][state || "base"].value; +} + +export function shadow(theme) { + return { + blur: 16, + color: chroma("black").alpha(theme.shadowAlpha.value).hex(), + offset: [0, 2], + }; +} diff --git a/styles/core.ts b/styles/core.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c63b2285ea0406363f05938e956029db5cc39dd --- /dev/null +++ b/styles/core.ts @@ -0,0 +1,38 @@ +export type Color = string; + +export default { + fontFamily: { + sans: "Zed Sans", + mono: "Zed Mono", + }, + fontSize: { + "3xs": { + value: "8", + type: "fontSizes", + }, + "2xs": { + value: "10", + type: "fontSizes", + }, + xs: { + value: "12", + type: "fontSizes", + }, + sm: { + value: "14", + type: "fontSizes", + }, + md: { + value: "16", + type: "fontSizes", + }, + lg: { + value: "18", + type: "fontSizes", + }, + xl: { + value: "20", + type: "fontSizes", + }, + }, +}; diff --git a/styles/package-lock.json b/styles/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..3abb465628bd5400de8fccf399c5e62025600ab1 --- /dev/null +++ b/styles/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "styles", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "styles", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "chroma-js": "^2.4.2" + } + }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + } + }, + "dependencies": { + "chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + } + } +} diff --git a/styles/package.json b/styles/package.json new file mode 100644 index 0000000000000000000000000000000000000000..92f0546c561f768847c081fca7465d28822798ff --- /dev/null +++ b/styles/package.json @@ -0,0 +1,14 @@ +{ + "name": "styles", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "chroma-js": "^2.4.2" + } +} diff --git a/styles/selector-modal.ts b/styles/selector-modal.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7101c915138e61d6147f4f12e82e58310ae9637 --- /dev/null +++ b/styles/selector-modal.ts @@ -0,0 +1,59 @@ +import { backgroundColor, border, player, shadow, text } from "./components"; +import Theme from "./theme"; + +export function selectorModal(theme: Theme): Object { + const item = { + padding: { + bottom: 4, + left: 16, + right: 16, + top: 4, + }, + cornerRadius: 6, + text: text(theme, "sans", "secondary"), + highlightText: text(theme, "sans", "feature", { weight: "bold" }), + }; + + const activeItem = { + ...item, + background: backgroundColor(theme, 500, "active"), + text: text(theme, "sans", "primary"), + }; + + return { + background: backgroundColor(theme, 500), + cornerRadius: 6, + padding: 8, + item, + activeItem, + border: border(theme, "primary"), + empty: { + text: text(theme, "sans", "muted"), + padding: { + bottom: 4, + left: 16, + right: 16, + top: 8, + }, + }, + inputEditor: { + background: backgroundColor(theme, 300), + corner_radius: 6, + placeholderText: text(theme, "sans", "placeholder"), + selection: player(theme, 1).selection, + text: text(theme, "mono", "primary"), + border: border(theme, "primary"), + padding: { + bottom: 7, + left: 16, + right: 16, + top: 7, + }, + }, + margin: { + bottom: 52, + top: 52, + }, + shadow: shadow(theme), + }; +} diff --git a/styles/theme.ts b/styles/theme.ts new file mode 100644 index 0000000000000000000000000000000000000000..5363a8c01c08697f90fa9a37ffba2c6d50305c5c --- /dev/null +++ b/styles/theme.ts @@ -0,0 +1,121 @@ +export type Color = string; +export type Weight = + | "thin" + | "extra_light" + | "light" + | "normal" + | "medium" + | "semibold" + | "bold" + | "extra_bold" + | "black"; + +interface SyntaxHighlightStyle { + color: { value: Color }; + weight: { value: Weight }; +} + +interface Player { + baseColor: { + value: Color; + }; + cursorColor: { + value: Color; + }; + selectionColor: { + value: Color; + }; + borderColor: { + value: Color; + }; +} + +export interface BackgroundColor { + base: { + value: Color; + }; + hover: { + value: Color; + }; + active: { + value: Color; + }; + focused: { + value: Color; + }; +} + +export default interface Theme { + backgroundColor: { + 100: BackgroundColor; + 300: BackgroundColor; + 500: BackgroundColor; + }; + borderColor: { + primary: { + value: Color; + }; + secondary: { + value: Color; + }; + muted: { + value: Color; + }; + focused: { + value: Color; + }; + active: { + value: Color; + }; + }; + textColor: { + primary: { + value: Color; + }; + secondary: { + value: Color; + }; + muted: { + value: Color; + }; + placeholder: { + value: Color; + }; + active: { + value: Color; + }; + feature: { + value: Color; + }; + }; + syntax: { + primary: SyntaxHighlightStyle; + comment: SyntaxHighlightStyle; + punctuation: SyntaxHighlightStyle; + constant: SyntaxHighlightStyle; + keyword: SyntaxHighlightStyle; + function: SyntaxHighlightStyle; + type: SyntaxHighlightStyle; + variant: SyntaxHighlightStyle; + property: SyntaxHighlightStyle; + enum: SyntaxHighlightStyle; + operator: SyntaxHighlightStyle; + string: SyntaxHighlightStyle; + number: SyntaxHighlightStyle; + boolean: SyntaxHighlightStyle; + predictive: SyntaxHighlightStyle; + }; + player: { + 1: Player; + 2: Player; + 3: Player; + 4: Player; + 5: Player; + 6: Player; + 7: Player; + 8: Player; + }; + shadowAlpha: { + value: number; + }; +} From bfce4a61041e7353492cd5f6ca61d235addb142a Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 29 Mar 2022 15:33:03 -0400 Subject: [PATCH 40/68] WIP: Add `rose` color tokens to `core.ts` --- styles/core.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/styles/core.ts b/styles/core.ts index 6c63b2285ea0406363f05938e956029db5cc39dd..164b6dba003b391e73717d232fb8b9c94ecbcba2 100644 --- a/styles/core.ts +++ b/styles/core.ts @@ -1,6 +1,51 @@ +import chroma from "chroma-js"; + export type Color = string; +function getColorRamp(colorName, baseColor, steps = 10) { + let hsl = chroma(baseColor).hsl(); + let h = Math.round(hsl[0]); + let lightColor = chroma.hsl(h, 0.88, 0.96).hex(); + let darkColor = chroma.hsl(h, 0.68, 0.32).hex(); + + let ramp = chroma + .scale([lightColor, baseColor, darkColor]) + .domain([0, 0.5, 1]) + .mode("hsl") + .gamma(1) + .correctLightness(true) + .padding([0, 0.15]) + .colors(steps); + + let tokens = {}; + let token = {}; + let colorNumber = 0; + + for (let i = 0; i < steps; i++) { + if (i !== 0) { + colorNumber = i * 100; + } + + token = { + [`${colorName}_${colorNumber}`]: { + value: ramp[i].value, + rootValue: baseColor, + step: i, + type: "color", + }, + }; + + Object.assign(token, tokens); + } + + return tokens; +} + export default { + color: { + rose: getColorRamp("rose", "#F43F5E", 10), + }, + fontFamily: { sans: "Zed Sans", mono: "Zed Mono", From 1f71e742c5834ac08a58e4be014df92d238554c3 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 29 Mar 2022 17:10:46 -0400 Subject: [PATCH 41/68] WIP: Color WIP --- styles/core.color.ts | 93 ++++++++++++++++++++++++++++++++++++++++++++ styles/core.ts | 45 +-------------------- 2 files changed, 95 insertions(+), 43 deletions(-) create mode 100644 styles/core.color.ts diff --git a/styles/core.color.ts b/styles/core.color.ts new file mode 100644 index 0000000000000000000000000000000000000000..004e7209a2c124bfa74bfaec6d598389e187d9ad --- /dev/null +++ b/styles/core.color.ts @@ -0,0 +1,93 @@ +import chroma from "chroma-js"; + +export type Color = string; + +function returnTokens( + colorName: string, + ramp: Array, // help, have no clue on type here +) { + let tokens = {}; + let token = {}; + let colorNumber = 0; + let increment = 0; + + for (let i = 0; i < ramp.len; i++) { + if (i > 11 ) { + increment = 50; + } else { + increment = 100; + } + + if (i !== 0) { + colorNumber = i * increment; + } + + token = { + [`${colorName}_${colorNumber}`]: { + value: ramp[i].value, + step: i, + type: "color", + }, + }; + + Object.assign(token, tokens); + } + return tokens; +} + +function oneColorRamp( + colorName: string, + baseColor: string, + steps: number = 10 +) { + let hsl = chroma(baseColor).hsl(); + let h = Math.round(hsl[0]); + let lightColor = chroma.hsl(h, 0.88, 0.96).hex(); + let darkColor = chroma.hsl(h, 0.68, 0.32).hex(); + + let ramp = chroma + .scale([lightColor, baseColor, darkColor]) + .domain([0, 0.5, 1]) + .mode("hsl") + .gamma(1) + .correctLightness(true) + .padding([0, 0.15]) + .colors(steps) + .hex(); + + return returnTokens(colorName, ramp); +} + +function colorRamp( + colorName: string, + startColor: string, + endColor: string, + steps: number +) { + let ramp = chroma.scale([startColor, endColor]).mode("hsl").colors(steps).hex(); + + return returnTokens(colorName, ramp); +} + +export default { + color: { + neutral: colorRamp("neutral", "black", "white", 21), // colorName, startColor, endColor, steps + rose: oneColorRamp("rose", "#F43F5EFF"), // colorName, baseColor, steps(optional) + red: oneColorRamp("red", "#EF4444FF"), + orange: oneColorRamp("orange", "#F97316FF"), + amber: oneColorRamp("amber", "#F59E0BFF"), + yellow: oneColorRamp("yellow", "#EAB308FF"), + lime: oneColorRamp("lime", "#84CC16FF"), + green: oneColorRamp("green", "#22C55EFF"), + emerald: oneColorRamp("emerald", "#10B981FF"), + teal: oneColorRamp("teal", "#14B8A6FF"), + cyan: oneColorRamp("cyan", "#06BBD4FF"), + sky: oneColorRamp("sky", "#0EA5E9FF"), + blue: oneColorRamp("blue", "#3B82F6FF"), + indigo: oneColorRamp("indigo", "#6366F1FF"), + violet: oneColorRamp("violet", "#8B5CF6FF"), + purple: oneColorRamp("purple", "#A855F7FF"), + fuschia: oneColorRamp("fuschia", "#D946E4FF"), + pink: oneColorRamp("pink", "#EC4899FF"), + }, +}; diff --git a/styles/core.ts b/styles/core.ts index 164b6dba003b391e73717d232fb8b9c94ecbcba2..6444ef9a1c96b26c85ec5181871005650443ce22 100644 --- a/styles/core.ts +++ b/styles/core.ts @@ -1,50 +1,9 @@ -import chroma from "chroma-js"; +import color from "./core.color"; export type Color = string; -function getColorRamp(colorName, baseColor, steps = 10) { - let hsl = chroma(baseColor).hsl(); - let h = Math.round(hsl[0]); - let lightColor = chroma.hsl(h, 0.88, 0.96).hex(); - let darkColor = chroma.hsl(h, 0.68, 0.32).hex(); - - let ramp = chroma - .scale([lightColor, baseColor, darkColor]) - .domain([0, 0.5, 1]) - .mode("hsl") - .gamma(1) - .correctLightness(true) - .padding([0, 0.15]) - .colors(steps); - - let tokens = {}; - let token = {}; - let colorNumber = 0; - - for (let i = 0; i < steps; i++) { - if (i !== 0) { - colorNumber = i * 100; - } - - token = { - [`${colorName}_${colorNumber}`]: { - value: ramp[i].value, - rootValue: baseColor, - step: i, - type: "color", - }, - }; - - Object.assign(token, tokens); - } - - return tokens; -} - export default { - color: { - rose: getColorRamp("rose", "#F43F5E", 10), - }, + color: color, fontFamily: { sans: "Zed Sans", From 8b33a58076e5a0c2b41a58f2e34d5c9a6ebe5310 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 29 Mar 2022 16:28:19 -0600 Subject: [PATCH 42/68] Express workspace in terms of new components Co-Authored-By: Nate Butler <1714999+iamnbutler@users.noreply.github.com> --- styles/app.ts | 155 +++------------------------------------ styles/components.ts | 23 +++++- styles/core.color.ts | 93 ----------------------- styles/core.ts | 26 +++++-- styles/lib.ts | 44 +++++++++++ styles/package-lock.json | 11 +++ styles/package.json | 1 + styles/selector-modal.ts | 2 +- styles/theme.ts | 46 ++++++++++++ styles/workspace.ts | 133 +++++++++++++++++++++++++++++++++ 10 files changed, 288 insertions(+), 246 deletions(-) delete mode 100644 styles/core.color.ts create mode 100644 styles/lib.ts create mode 100644 styles/workspace.ts diff --git a/styles/app.ts b/styles/app.ts index a7ae4348bea1d2e0861d0d4a957cd6eb7a3c7adf..4f40577ae9ada410e9cab6c76bfb950660b6b94b 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -1,147 +1,12 @@ -import { selectorModal } from "./selector-modal"; +import { backgroundColor } from "./components"; +import selectorModal from "./selector-modal"; +import workspace from "./workspace"; import Theme from "./theme"; export default function app(theme: Theme): Object { return { selector: selectorModal(theme), - workspace: { - background: "$surface.500", - leaderBorderOpacity: 0.7, - leader_border_width: 2.0, - active_tab: { - background: "$surface.300", - extends: "$workspace.tab", - text: "$text.primary", - border: { - bottom: false, - }, - }, - left_sidebar: { - extends: "$workspace.sidebar", - border: { - color: "$border.primary", - right: true, - width: 1, - }, - }, - pane_divider: { - color: "$border.primary", - width: 1, - }, - right_sidebar: { - extends: "$workspace.sidebar", - border: { - color: "$border.primary", - left: true, - width: 1, - }, - }, - sidebar: { - width: 30, - active_item: { - extends: "$workspace.sidebar.item", - icon_color: "$text.primary.color", - }, - border: { - color: "$border.primary", - right: true, - width: 1, - }, - item: { - height: "$workspace.tab.height", - icon_color: "$text.muted.color", - icon_size: 18, - }, - resize_handle: { - background: "$border.primary", - padding: { - left: 1, - }, - }, - }, - status_bar: { - cursor_position: "$text.muted", - diagnostic_message: "$text.muted", - height: 24, - item_spacing: 8, - lsp_message: "$text.muted", - padding: { - left: 6, - right: 6, - }, - }, - tab: { - height: 34, - icon_close: "$text.muted.color", - icon_close_active: "$text.primary.color", - icon_conflict: "$status.warn", - icon_dirty: "$status.info", - icon_width: 8, - spacing: 10, - text: "$text.muted", - border: { - bottom: true, - color: "$border.primary", - left: true, - overlay: true, - width: 1, - }, - padding: { - left: 12, - right: 12, - }, - }, - titlebar: { - avatar_width: 18, - height: 32, - share_icon_active_color: "$text.primary.color", - share_icon_color: "$text.muted.color", - title: "$text.primary", - avatar: { - corner_radius: 10, - border: { - color: "#00000088", - width: 1, - }, - }, - avatar_ribbon: { - background: "#ff0000", - height: 3, - width: 12, - }, - border: { - bottom: true, - color: "$border.primary", - width: 1, - }, - hovered_sign_in_prompt: { - color: "$text.secondary.color", - extends: "$workspace.titlebar.sign_in_prompt", - }, - offline_icon: { - color: "$text.muted.color", - width: 16, - padding: { - right: 4, - }, - }, - outdated_warning: { - extends: "$text.muted", - size: 13, - }, - sign_in_prompt: { - extends: "$text.muted", - size: 13, - underline: true, - padding: { - right: 8, - }, - }, - }, - toolbar: { - height: 44, - }, - }, + workspace: workspace(theme), chat_panel: { extends: "$panel", channel_name: { @@ -205,7 +70,7 @@ export default function app(theme: Theme): Object { extends: "$chat_panel.sign_in_prompt", }, input_editor: { - background: "$surface.300", + background: backgroundColor(theme, 300), corner_radius: 6, placeholder_text: "$text.muted", selection: "$selection.host", @@ -306,7 +171,7 @@ export default function app(theme: Theme): Object { }, editor: { active_line_background: "$state.active_line", - background: "$surface.300", + background: backgroundColor(theme, 300), code_actions_indicator: "$text.muted.color", diff_background_deleted: "$state.deleted_line", diff_background_inserted: "$state.inserted_line", @@ -314,7 +179,7 @@ export default function app(theme: Theme): Object { document_highlight_write_background: "#99999916", error_color: "$status.bad", guest_selections: "$selection.guests", - gutter_background: "$surface.300", + gutter_background: backgroundColor(theme, 300), gutter_padding_factor: 2.5, highlighted_line_background: "$state.highlighted_line", line_number: "$text.muted.color", @@ -502,7 +367,7 @@ export default function app(theme: Theme): Object { }, }, project_diagnostics: { - background: "$surface.300", + background: backgroundColor(theme, 300), tab_icon_spacing: 4, tab_icon_width: 13, tab_summary_spacing: 10, @@ -547,7 +412,7 @@ export default function app(theme: Theme): Object { }, }, search: { - background: "$surface.300", + background: backgroundColor(theme, 300), match_background: "$state.highlighted_line", tab_icon_spacing: 4, tab_icon_width: 14, @@ -599,7 +464,7 @@ export default function app(theme: Theme): Object { padding: 6, }, option_button: { - background: "$surface.300", + background: backgroundColor(theme, 300), corner_radius: 6, extends: "$text.secondary", border: { diff --git a/styles/components.ts b/styles/components.ts index 226d1d9e374274ce82938f85c1a73d0c669a468c..9cc58046ffba77646dc07342b1485e0877305f69 100644 --- a/styles/components.ts +++ b/styles/components.ts @@ -1,5 +1,6 @@ import chroma from "chroma-js"; -import core, { Color } from "./core"; +import core from "./core"; +import { Color } from "./lib"; import Theme, { BackgroundColor, Weight } from "./theme"; export function text( @@ -19,13 +20,31 @@ export function text( }; } -export function border(theme: Theme, color: keyof Theme["borderColor"]) { +export interface BorderOptions { + width?: number; + top?: boolean; + bottom?: boolean; + left?: boolean; + right?: boolean; + overlay?: boolean; +} + +export function border( + theme: Theme, + color: keyof Theme["borderColor"], + options?: BorderOptions +) { return { color: theme.borderColor[color].value, width: 1, + ...options, }; } +export function iconColor(theme: Theme, color: keyof Theme["iconColor"]) { + return theme.iconColor[color].value; +} + export interface Player { selection: { cursor: Color; diff --git a/styles/core.color.ts b/styles/core.color.ts deleted file mode 100644 index 004e7209a2c124bfa74bfaec6d598389e187d9ad..0000000000000000000000000000000000000000 --- a/styles/core.color.ts +++ /dev/null @@ -1,93 +0,0 @@ -import chroma from "chroma-js"; - -export type Color = string; - -function returnTokens( - colorName: string, - ramp: Array, // help, have no clue on type here -) { - let tokens = {}; - let token = {}; - let colorNumber = 0; - let increment = 0; - - for (let i = 0; i < ramp.len; i++) { - if (i > 11 ) { - increment = 50; - } else { - increment = 100; - } - - if (i !== 0) { - colorNumber = i * increment; - } - - token = { - [`${colorName}_${colorNumber}`]: { - value: ramp[i].value, - step: i, - type: "color", - }, - }; - - Object.assign(token, tokens); - } - return tokens; -} - -function oneColorRamp( - colorName: string, - baseColor: string, - steps: number = 10 -) { - let hsl = chroma(baseColor).hsl(); - let h = Math.round(hsl[0]); - let lightColor = chroma.hsl(h, 0.88, 0.96).hex(); - let darkColor = chroma.hsl(h, 0.68, 0.32).hex(); - - let ramp = chroma - .scale([lightColor, baseColor, darkColor]) - .domain([0, 0.5, 1]) - .mode("hsl") - .gamma(1) - .correctLightness(true) - .padding([0, 0.15]) - .colors(steps) - .hex(); - - return returnTokens(colorName, ramp); -} - -function colorRamp( - colorName: string, - startColor: string, - endColor: string, - steps: number -) { - let ramp = chroma.scale([startColor, endColor]).mode("hsl").colors(steps).hex(); - - return returnTokens(colorName, ramp); -} - -export default { - color: { - neutral: colorRamp("neutral", "black", "white", 21), // colorName, startColor, endColor, steps - rose: oneColorRamp("rose", "#F43F5EFF"), // colorName, baseColor, steps(optional) - red: oneColorRamp("red", "#EF4444FF"), - orange: oneColorRamp("orange", "#F97316FF"), - amber: oneColorRamp("amber", "#F59E0BFF"), - yellow: oneColorRamp("yellow", "#EAB308FF"), - lime: oneColorRamp("lime", "#84CC16FF"), - green: oneColorRamp("green", "#22C55EFF"), - emerald: oneColorRamp("emerald", "#10B981FF"), - teal: oneColorRamp("teal", "#14B8A6FF"), - cyan: oneColorRamp("cyan", "#06BBD4FF"), - sky: oneColorRamp("sky", "#0EA5E9FF"), - blue: oneColorRamp("blue", "#3B82F6FF"), - indigo: oneColorRamp("indigo", "#6366F1FF"), - violet: oneColorRamp("violet", "#8B5CF6FF"), - purple: oneColorRamp("purple", "#A855F7FF"), - fuschia: oneColorRamp("fuschia", "#D946E4FF"), - pink: oneColorRamp("pink", "#EC4899FF"), - }, -}; diff --git a/styles/core.ts b/styles/core.ts index 6444ef9a1c96b26c85ec5181871005650443ce22..e9e81982e456c0ffe151b83ac36767d62140c6ba 100644 --- a/styles/core.ts +++ b/styles/core.ts @@ -1,10 +1,6 @@ -import color from "./core.color"; - -export type Color = string; +import { colorRamp } from "./lib"; export default { - color: color, - fontFamily: { sans: "Zed Sans", mono: "Zed Mono", @@ -39,4 +35,24 @@ export default { type: "fontSizes", }, }, + color: { + neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), + rose: colorRamp("#F43F5EFF"), + red: colorRamp("#EF4444FF"), + orange: colorRamp("#F97316FF"), + amber: colorRamp("#F59E0BFF"), + yellow: colorRamp("#EAB308FF"), + lime: colorRamp("#84CC16FF"), + green: colorRamp("#22C55EFF"), + emerald: colorRamp("#10B981FF"), + teal: colorRamp("#14B8A6FF"), + cyan: colorRamp("#06BBD4FF"), + sky: colorRamp("#0EA5E9FF"), + blue: colorRamp("#3B82F6FF"), + indigo: colorRamp("#6366F1FF"), + violet: colorRamp("#8B5CF6FF"), + purple: colorRamp("#A855F7FF"), + fuschia: colorRamp("#D946E4FF"), + pink: colorRamp("#EC4899FF"), + }, }; diff --git a/styles/lib.ts b/styles/lib.ts new file mode 100644 index 0000000000000000000000000000000000000000..b59f4fa69479a1f886229afe1953284f6626f9d8 --- /dev/null +++ b/styles/lib.ts @@ -0,0 +1,44 @@ +import chroma, { Scale } from "chroma-js"; + +export type Color = string; +export type ColorRampStep = { value: Color; type: "color"; step: number }; +export type ColorRamp = { + [index: number]: ColorRampStep; +}; + +export function colorRamp( + color: Color | [Color, Color], + options?: { steps?: number; increment?: number } +): ColorRamp { + let scale: Scale; + if (Array.isArray(color)) { + const [startColor, endColor] = color; + scale = chroma.scale([startColor, endColor]); + } else { + let hue = Math.round(chroma(color).hsl()[0]); + let startColor = chroma.hsl(hue, 0.88, 0.96); + let endColor = chroma.hsl(hue, 0.68, 0.32); + scale = chroma + .scale([startColor, color, endColor]) + .domain([0, 0.5, 1]) + .mode("hsl") + .gamma(1) + .correctLightness(true) + .padding([0, 0.15]); + } + + const ramp: ColorRamp = {}; + const steps = options?.steps || 10; + const increment = options?.increment || 100; + + scale.colors(steps, "hex").forEach((color, ix) => { + const step = ix * increment; + ramp[step] = { + value: color, + step, + type: "color", + }; + }); + + return ramp; +} diff --git a/styles/package-lock.json b/styles/package-lock.json index 3abb465628bd5400de8fccf399c5e62025600ab1..7b8503bf720d572d64bb9179a78489beaa068cb4 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -9,9 +9,15 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@types/chroma-js": "^2.1.3", "chroma-js": "^2.4.2" } }, + "node_modules/@types/chroma-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", + "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" + }, "node_modules/chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", @@ -19,6 +25,11 @@ } }, "dependencies": { + "@types/chroma-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", + "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" + }, "chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", diff --git a/styles/package.json b/styles/package.json index 92f0546c561f768847c081fca7465d28822798ff..c66da8718b6d4f2047cbc4e7580036946dab1fb8 100644 --- a/styles/package.json +++ b/styles/package.json @@ -9,6 +9,7 @@ "author": "", "license": "ISC", "dependencies": { + "@types/chroma-js": "^2.1.3", "chroma-js": "^2.4.2" } } diff --git a/styles/selector-modal.ts b/styles/selector-modal.ts index f7101c915138e61d6147f4f12e82e58310ae9637..ddba32683a976153eac6fc0f49f6a5df9a835a1f 100644 --- a/styles/selector-modal.ts +++ b/styles/selector-modal.ts @@ -1,7 +1,7 @@ import { backgroundColor, border, player, shadow, text } from "./components"; import Theme from "./theme"; -export function selectorModal(theme: Theme): Object { +export default function selectorModal(theme: Theme): Object { const item = { padding: { bottom: 4, diff --git a/styles/theme.ts b/styles/theme.ts index 5363a8c01c08697f90fa9a37ffba2c6d50305c5c..ddfa6414f49e5e94236f3c2d316896869f832986 100644 --- a/styles/theme.ts +++ b/styles/theme.ts @@ -1,3 +1,5 @@ +import { colorRamp } from "./lib"; + export type Color = string; export type Weight = | "thin" @@ -87,6 +89,50 @@ export default interface Theme { feature: { value: Color; }; + ok: { + value: Color; + }; + error: { + value: Color; + }; + warning: { + value: Color; + }; + info: { + value: Color; + }; + }; + iconColor: { + primary: { + value: Color; + }; + secondary: { + value: Color; + }; + muted: { + value: Color; + }; + placeholder: { + value: Color; + }; + active: { + value: Color; + }; + feature: { + value: Color; + }; + ok: { + value: Color; + }; + error: { + value: Color; + }; + warning: { + value: Color; + }; + info: { + value: Color; + }; }; syntax: { primary: SyntaxHighlightStyle; diff --git a/styles/workspace.ts b/styles/workspace.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ecb3a378c8d1a5acedc5100203c9b9306e36dca --- /dev/null +++ b/styles/workspace.ts @@ -0,0 +1,133 @@ +import { backgroundColor, border, iconColor, text } from "./components"; +import Theme from "./theme"; + +export default function workspace(theme: Theme) { + const signInPrompt = { + ...text(theme, "sans", "secondary"), + size: 13, + underline: true, + padding: { + right: 8, + }, + }; + + const tab = { + height: 34, + iconClose: iconColor(theme, "secondary"), + iconCloseActive: iconColor(theme, "active"), + iconConflict: iconColor(theme, "warning"), + iconDirty: iconColor(theme, "info"), + iconWidth: 8, + spacing: 10, + text: text(theme, "mono", "secondary"), + border: border(theme, "primary", { + left: true, + bottom: true, + overlay: true, + }), + padding: { + left: 12, + right: 12, + }, + }; + + const activeTab = { + ...tab, + background: backgroundColor(theme, 300), + text: text(theme, "mono", "primary"), + border: { + ...tab.border, + bottom: false, + }, + }; + + const sidebarItem = { + height: "$workspace.tab.height", + iconColor: "$text.muted.color", + iconSize: 18, + }; + const sidebar = { + width: 30, + border: border(theme, "primary", { right: true }), + item: sidebarItem, + activeItem: { + ...sidebarItem, + iconColor: iconColor(theme, "primary"), + }, + resizeHandle: { + background: border(theme, "primary").color, + padding: { + left: 1, + }, + }, + }; + + return { + background: backgroundColor(theme, 500), + leaderBorderOpacity: 0.7, + leaderBorderWidth: 2.0, + tab, + activeTab, + leftSidebar: { + ...sidebar, + border: border(theme, "primary", { right: true }), + }, + rightSidebar: { + ...sidebar, + border: border(theme, "primary", { left: true }), + }, + paneDivider: { + color: border(theme, "primary").color, + width: 1, + }, + status_bar: { + height: 24, + itemSpacing: 8, + padding: { + left: 6, + right: 6, + }, + cursorPosition: text(theme, "sans", "muted"), + diagnosticMessage: text(theme, "sans", "muted"), + lspMessage: text(theme, "sans", "muted"), + }, + titlebar: { + avatarWidth: 18, + height: 32, + shareIconColor: iconColor(theme, "secondary"), + shareIconActiveColor: iconColor(theme, "active"), + title: text(theme, "sans", "primary"), + avatar: { + cornerRadius: 10, + border: { + color: "#00000088", + width: 1, + }, + }, + avatarRibbon: { + height: 3, + width: 12, + }, + border: border(theme, "primary", { bottom: true }), + signInPrompt, + hoveredSignInPrompt: { + ...signInPrompt, + ...text(theme, "mono", "active"), + }, + offlineIcon: { + color: iconColor(theme, "muted"), + width: 16, + padding: { + right: 4, + }, + }, + outdatedWarning: { + ...text(theme, "sans", "muted"), + size: 13, + }, + }, + toolbar: { + height: 44, + }, + }; +} From cb3c111401b5ed438733826d7cc850ff5f9bfd62 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 30 Mar 2022 17:59:35 -0600 Subject: [PATCH 43/68] Convert editor styles to TypeScript --- styles/app.ts | 201 +------------------------------------------ styles/components.ts | 4 +- styles/editor.ts | 143 ++++++++++++++++++++++++++++++ styles/theme.ts | 65 ++++++++++++++ 4 files changed, 214 insertions(+), 199 deletions(-) create mode 100644 styles/editor.ts diff --git a/styles/app.ts b/styles/app.ts index 4f40577ae9ada410e9cab6c76bfb950660b6b94b..a421da8f07dc854931d64268d84ae2cf9f4ec5e3 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -1,13 +1,15 @@ import { backgroundColor } from "./components"; import selectorModal from "./selector-modal"; import workspace from "./workspace"; +import editor from "./editor"; import Theme from "./theme"; export default function app(theme: Theme): Object { return { selector: selectorModal(theme), workspace: workspace(theme), - chat_panel: { + editor: editor(theme), + chatPanel: { extends: "$panel", channel_name: { extends: "$text.primary", @@ -169,203 +171,6 @@ export default function app(theme: Theme): Object { extends: "$contacts_panel.project", }, }, - editor: { - active_line_background: "$state.active_line", - background: backgroundColor(theme, 300), - code_actions_indicator: "$text.muted.color", - diff_background_deleted: "$state.deleted_line", - diff_background_inserted: "$state.inserted_line", - document_highlight_read_background: "#99999920", - document_highlight_write_background: "#99999916", - error_color: "$status.bad", - guest_selections: "$selection.guests", - gutter_background: backgroundColor(theme, 300), - gutter_padding_factor: 2.5, - highlighted_line_background: "$state.highlighted_line", - line_number: "$text.muted.color", - line_number_active: "$text.primary.color", - rename_fade: 0.6, - selection: "$selection.host", - text_color: "$text.secondary.color", - unnecessary_code_fade: 0.5, - autocomplete: { - background: "$surface.100", - corner_radius: 6, - padding: 6, - border: { - color: "$border.secondary", - width: 2, - }, - hovered_item: { - background: "$state.hover", - extends: "$editor.autocomplete.item", - }, - item: { - corner_radius: 6, - padding: { - bottom: 2, - left: 6, - right: 6, - top: 2, - }, - }, - margin: { - left: -14, - }, - match_highlight: { - color: "$editor.syntax.keyword.color", - weight: "$editor.syntax.keyword.weight", - }, - selected_item: { - background: "$state.selected", - extends: "$editor.autocomplete.item", - }, - }, - diagnostic_header: { - background: "$editor.background", - icon_width_factor: 1.5, - text_scale_factor: 0.857, - border: { - bottom: true, - color: "$border.secondary", - top: true, - width: 1, - }, - code: { - extends: "$text.muted", - size: 14, - margin: { - left: 10, - }, - }, - message: { - highlight_text: { - extends: "$text.primary", - size: 14, - weight: "bold", - }, - text: { - extends: "$text.secondary", - size: 14, - }, - }, - }, - diagnostic_path_header: { - background: "$state.active_line", - text_scale_factor: 0.857, - filename: { - extends: "$text.primary", - size: 14, - }, - path: { - extends: "$text.muted", - size: 14, - margin: { - left: 12, - }, - }, - }, - error_diagnostic: { - text_scale_factor: 0.857, - header: { - border: { - color: "$border.primary", - top: true, - width: 1, - }, - }, - message: { - highlight_text: { - color: "$status.bad", - extends: "$text.secondary", - size: 14, - weight: "bold", - }, - text: { - color: "$status.bad", - extends: "$text.secondary", - size: 14, - }, - }, - }, - hint_diagnostic: { - extends: "$editor.error_diagnostic", - message: { - highlight_text: { - color: "$status.info", - }, - text: { - color: "$status.info", - }, - }, - }, - information_diagnostic: { - extends: "$editor.error_diagnostic", - message: { - highlight_text: { - color: "$status.info", - }, - text: { - color: "$status.info", - }, - }, - }, - invalid_error_diagnostic: { - extends: "$editor.error_diagnostic", - message: { - highlight_text: { - color: "$text.muted.color", - }, - text: { - color: "$text.muted.color", - }, - }, - }, - invalid_hint_diagnostic: { - extends: "$editor.hint_diagnostic", - message: { - highlight_text: { - color: "$text.muted.color", - }, - text: { - color: "$text.muted.color", - }, - }, - }, - invalid_information_diagnostic: { - extends: "$editor.information_diagnostic", - message: { - highlight_text: { - color: "$text.muted.color", - }, - text: { - color: "$text.muted.color", - }, - }, - }, - invalid_warning_diagnostic: { - extends: "$editor.warning_diagnostic", - message: { - highlight_text: { - color: "$text.muted.color", - }, - text: { - color: "$text.muted.color", - }, - }, - }, - warning_diagnostic: { - extends: "$editor.error_diagnostic", - message: { - highlight_text: { - color: "$status.warn", - }, - text: { - color: "$status.warn", - }, - }, - }, - }, project_diagnostics: { background: backgroundColor(theme, 300), tab_icon_spacing: 4, diff --git a/styles/components.ts b/styles/components.ts index 9cc58046ffba77646dc07342b1485e0877305f69..14becaf2af30e94d4c6d3a0250b0e3f3aab52faf 100644 --- a/styles/components.ts +++ b/styles/components.ts @@ -3,10 +3,12 @@ import core from "./core"; import { Color } from "./lib"; import Theme, { BackgroundColor, Weight } from "./theme"; +export type TextColor = keyof Theme["textColor"]; + export function text( theme: Theme, fontFamily: keyof typeof core.fontFamily, - color: keyof Theme["textColor"], + color: TextColor, properties?: { size?: keyof typeof core["fontSize"]; weight?: Weight } ) { const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md"; diff --git a/styles/editor.ts b/styles/editor.ts new file mode 100644 index 0000000000000000000000000000000000000000..9edfdc4716bea35b4c7e3cf83967383b4f6a3850 --- /dev/null +++ b/styles/editor.ts @@ -0,0 +1,143 @@ +import { + backgroundColor, + border, + iconColor, + player, + text, + TextColor, +} from "./components"; +import Theme from "./theme"; + +export default function editor(theme: Theme) { + const autocompleteItem = { + cornerRadius: 6, + padding: { + bottom: 2, + left: 6, + right: 6, + top: 2, + }, + }; + + function diagnostic(theme: Theme, color: TextColor) { + return { + textScaleFactor: 0.857, + header: { + border: border(theme, "primary", { + top: true, + }), + }, + message: { + text: { + ...text(theme, "sans", color), + size: 14, + }, + highlightText: { + ...text(theme, "sans", color, { weight: "bold" }), + size: 14, + }, + }, + }; + } + + return { + textColor: theme.textColor.secondary.value, + background: backgroundColor(theme, 300), + activeLineBackground: theme.editor.line.active.value, + codeActionsIndicator: iconColor(theme, "secondary"), + diffBackgroundDeleted: backgroundColor(theme, "error"), + diffBackgroundInserted: backgroundColor(theme, "ok"), + documentHighlightReadBackground: theme.editor.highlight.occurrence.value, + documentHighlightWriteBackground: theme.editor.highlight.occurrence.value, + errorColor: theme.textColor.error, + gutterBackground: backgroundColor(theme, 300), + gutterPaddingFactor: 2.5, + highlightedLineBackground: theme.editor.line.highlighted.value, + lineNumber: theme.editor.gutter.primary.value, + lineNumberActive: theme.editor.gutter.active, + renameFade: 0.6, + unnecessaryCodeFade: 0.5, + selection: player(theme, 1).selection, + guestSelections: [ + player(theme, 2).selection, + player(theme, 3).selection, + player(theme, 4).selection, + player(theme, 5).selection, + player(theme, 6).selection, + player(theme, 7).selection, + player(theme, 8).selection, + ], + autocomplete: { + background: backgroundColor(theme, 100), + cornerRadius: 6, + padding: 6, + border: border(theme, "secondary"), + item: autocompleteItem, + hoveredItem: { + ...autocompleteItem, + background: backgroundColor(theme, 100, "hover"), + }, + margin: { + left: -14, + }, + matchHighlight: { + color: theme.syntax.keyword.color.value, + weight: theme.syntax.keyword.weight.value, + }, + selectedItem: { + ...autocompleteItem, + background: backgroundColor(theme, 100, "active"), + }, + }, + diagnosticHeader: { + background: theme.editor.background.value, + iconWidthFactor: 1.5, + textScaleFactor: 0.857, + border: border(theme, "secondary", { + bottom: true, + top: true, + }), + code: { + ...text(theme, "mono", "muted"), + size: 14, + margin: { + left: 10, + }, + }, + message: { + highlightText: { + ...text(theme, "sans", "primary"), + size: 14, + weight: "bold", + }, + text: { + ...text(theme, "sans", "secondary"), + size: 14, + }, + }, + }, + diagnosticPathHeader: { + background: theme.editor.line.active, + textScaleFactor: 0.857, + filename: { + ...text(theme, "mono", "primary"), + size: 14, + }, + path: { + ...text(theme, "mono", "muted"), + size: 14, + margin: { + left: 12, + }, + }, + }, + errorDiagnostic: diagnostic(theme, "error"), + warningDiagnostic: diagnostic(theme, "warning"), + informationDiagnostic: diagnostic(theme, "info"), + hintDiagnostic: diagnostic(theme, "info"), + invalidErrorDiagnostic: diagnostic(theme, "muted"), + invalidHintDiagnostic: diagnostic(theme, "muted"), + invalidInformationDiagnostic: diagnostic(theme, "muted"), + invalidWarningDiagnostic: diagnostic(theme, "muted"), + }; +} diff --git a/styles/theme.ts b/styles/theme.ts index ddfa6414f49e5e94236f3c2d316896869f832986..5220c962c9d2032d35b15e32d12547f92d4c4679 100644 --- a/styles/theme.ts +++ b/styles/theme.ts @@ -52,6 +52,10 @@ export default interface Theme { 100: BackgroundColor; 300: BackgroundColor; 500: BackgroundColor; + ok: BackgroundColor; + error: BackgroundColor; + warning: BackgroundColor; + info: BackgroundColor; }; borderColor: { primary: { @@ -134,6 +138,66 @@ export default interface Theme { value: Color; }; }; + editor: { + background: { + value: Color; + }; + indent_guide: { + value: Color; + }; + indent_guide_active: { + value: Color; + }; + line: { + active: { + value: Color; + }; + highlighted: { + value: Color; + }; + inserted: { + value: Color; + }; + deleted: { + value: Color; + }; + modified: { + value: Color; + }; + }; + highlight: { + selection: { + value: Color; + }; + occurrence: { + value: Color; + }; + activeOccurrence: { + value: Color; + }; + matchingBracket: { + value: Color; + }; + match: { + value: Color; + }; + activeMatch: { + value: Color; + }; + related: { + value: Color; + }; + }; + gutter: { + primary: { + value: Color; + }; + active: { + value: Color; + }; + }; + }; + syntax: { primary: SyntaxHighlightStyle; comment: SyntaxHighlightStyle; @@ -151,6 +215,7 @@ export default interface Theme { boolean: SyntaxHighlightStyle; predictive: SyntaxHighlightStyle; }; + player: { 1: Player; 2: Player; From 189db6311cdd13f3286652dedb831b33014492ed Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 30 Mar 2022 18:26:47 -0600 Subject: [PATCH 44/68] Convert project panel styles --- styles/app.ts | 180 +++++++++++++++++----------------------- styles/editor.ts | 38 +++------ styles/project-panel.ts | 32 +++++++ styles/theme.ts | 4 +- 4 files changed, 124 insertions(+), 130 deletions(-) create mode 100644 styles/project-panel.ts diff --git a/styles/app.ts b/styles/app.ts index a421da8f07dc854931d64268d84ae2cf9f4ec5e3..ae0f0717bb5dc13e20db348d36bdeb1d562e0885 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -1,46 +1,67 @@ -import { backgroundColor } from "./components"; +import { backgroundColor, text } from "./components"; import selectorModal from "./selector-modal"; import workspace from "./workspace"; import editor from "./editor"; import Theme from "./theme"; +import projectPanel from "./project-panel"; + +export const panel = { + padding: { top: 12, left: 12, bottom: 12, right: 12 }, +}; export default function app(theme: Theme): Object { return { selector: selectorModal(theme), workspace: workspace(theme), editor: editor(theme), + projectDiagnostics: { + background: backgroundColor(theme, 300), + tabIconSpacing: 4, + tabIconWidth: 13, + tabSummarySpacing: 10, + emptyMessage: { + ...text(theme, "sans", "primary", { size: "lg" }), + }, + statusBarItem: { + ...text(theme, "sans", "muted"), + margin: { + right: 10, + }, + }, + }, + projectPanel: projectPanel(theme), chatPanel: { extends: "$panel", - channel_name: { + channelName: { extends: "$text.primary", weight: "bold", }, - channel_name_hash: { + channelNameHash: { text: "$text.muted", padding: { right: 8, }, }, - channel_select: { - active_item: { - extends: "$chat_panel.channel_select.item", + channelSelect: { + activeItem: { + extends: "$chatPanel.channel_select.item", name: "$text.primary", }, header: { - extends: "$chat_panel.channel_select.active_item", + extends: "$chat_panel.channel_select.activeItem", padding: { bottom: 4, left: 0, }, }, - hovered_active_item: { - extends: "$chat_panel.channel_select.hovered_item", + hoveredActiveItem: { + extends: "$chatPanel.channelSelect.hoveredItem", name: "$text.primary", }, - hovered_item: { + hoveredItem: { background: "$state.hover", - corner_radius: 6, - extends: "$chat_panel.channel_select.item", + cornerRadius: 6, + extends: "$chat_panel.channelSelect.item", }, item: { name: "$text.secondary", @@ -54,7 +75,7 @@ export default function app(theme: Theme): Object { }, menu: { background: "$surface.500", - corner_radius: 6, + cornerRadius: 6, padding: 4, border: { color: "$border.primary", @@ -67,14 +88,14 @@ export default function app(theme: Theme): Object { }, }, }, - hovered_sign_in_prompt: { + hoveredSignInPrompt: { color: "$text.secondary.color", - extends: "$chat_panel.sign_in_prompt", + extends: "$chatPanel.signInPrompt", }, - input_editor: { + inputEditor: { background: backgroundColor(theme, 300), - corner_radius: 6, - placeholder_text: "$text.muted", + cornerRadius: 6, + placeholderText: "$text.muted", selection: "$selection.host", text: "$text.primary", border: { @@ -102,8 +123,8 @@ export default function app(theme: Theme): Object { }, }, }, - pending_message: { - extends: "$chat_panel.message", + pendingMessage: { + extends: "$chatPanel.message", body: { color: "$text.muted.color", }, @@ -114,41 +135,41 @@ export default function app(theme: Theme): Object { color: "$text.muted.color", }, }, - sign_in_prompt: { + signInPrompt: { extends: "$text.primary", underline: true, }, }, - contacts_panel: { + contactsPanel: { extends: "$panel", - host_row_height: 28, - tree_branch_color: "$surface.100", - tree_branch_width: 1, - host_avatar: { - corner_radius: 10, + hostRowHeight: 28, + treeBranchColor: "$surface.100", + treeBranchWidth: 1, + hostAvatar: { + cornerRadius: 10, width: 18, }, - host_username: { + hostUsername: { extends: "$text.primary", padding: { left: 8, }, }, - hovered_shared_project: { + hoveredSharedProject: { background: "$state.hover", - corner_radius: 6, - extends: "$contacts_panel.shared_project", + cornerRadius: 6, + extends: "$contacts_panel.sharedProject", }, - hovered_unshared_project: { + hoveredUnsharedProject: { background: "$state.hover", - corner_radius: 6, - extends: "$contacts_panel.unshared_project", + cornerRadius: 6, + extends: "$contacts_panel.unsharedProject", }, project: { - guest_avatar_spacing: 4, + guestAvatarSpacing: 4, height: 24, - guest_avatar: { - corner_radius: 8, + guestAvatar: { + cornerRadius: 8, width: 14, }, name: { @@ -161,79 +182,34 @@ export default function app(theme: Theme): Object { left: 8, }, }, - shared_project: { - extends: "$contacts_panel.project", + sharedProject: { + extends: "$contactsPanel.project", name: { color: "$text.primary.color", }, }, - unshared_project: { - extends: "$contacts_panel.project", - }, - }, - project_diagnostics: { - background: backgroundColor(theme, 300), - tab_icon_spacing: 4, - tab_icon_width: 13, - tab_summary_spacing: 10, - empty_message: { - extends: "$text.primary", - size: 18, - }, - status_bar_item: { - extends: "$text.muted", - margin: { - right: 10, - }, - }, - }, - project_panel: { - extends: "$panel", - entry: { - height: 22, - icon_color: "$text.muted.color", - icon_size: 8, - icon_spacing: 8, - text: "$text.secondary", - }, - hovered_entry: { - background: "$state.hover", - extends: "$project_panel.entry", - }, - hovered_selected_entry: { - extends: "$project_panel.hovered_entry", - text: { - extends: "$text.primary", - }, - }, - padding: { - top: 6, - }, - selected_entry: { - extends: "$project_panel.entry", - text: { - extends: "$text.primary", - }, + unsharedProject: { + extends: "$contactsPanel.project", }, }, search: { background: backgroundColor(theme, 300), - match_background: "$state.highlighted_line", - tab_icon_spacing: 4, - tab_icon_width: 14, - active_hovered_option_button: { + matchBackground: "$state.highlightedLine", + tabIconSpacing: 4, + tabIconWidth: 14, + activeHoveredOptionButton: { background: "$surface.100", extends: "$search.option_button", }, - active_option_button: { + activeOptionButton: { background: "$surface.100", extends: "$search.option_button", }, editor: { background: "$surface.500", - corner_radius: 6, - max_width: 400, - placeholder_text: "$text.muted", + cornerRadius: 6, + maxWidth: 400, + placeholderText: "$text.muted", selection: "$selection.host", text: "$text.primary", border: { @@ -253,24 +229,24 @@ export default function app(theme: Theme): Object { top: 3, }, }, - hovered_option_button: { + hoveredOptionButton: { background: "$surface.100", - extends: "$search.option_button", + extends: "$search.optionButton", }, - invalid_editor: { + invalidEditor: { extends: "$search.editor", border: { color: "$status.bad", width: 1, }, }, - match_index: { + matchIndex: { extends: "$text.secondary", padding: 6, }, - option_button: { + optionButton: { background: backgroundColor(theme, 300), - corner_radius: 6, + cornerRadius: 6, extends: "$text.secondary", border: { color: "$border.primary", @@ -287,13 +263,13 @@ export default function app(theme: Theme): Object { top: 1, }, }, - option_button_group: { + optionButtonGroup: { padding: { left: 2, right: 2, }, }, - results_status: { + resultsStatus: { extends: "$text.primary", size: 18, }, diff --git a/styles/editor.ts b/styles/editor.ts index 9edfdc4716bea35b4c7e3cf83967383b4f6a3850..ea7012d2092ebd0d7df324762f4703693b32a89d 100644 --- a/styles/editor.ts +++ b/styles/editor.ts @@ -28,14 +28,11 @@ export default function editor(theme: Theme) { }), }, message: { - text: { - ...text(theme, "sans", color), - size: 14, - }, - highlightText: { - ...text(theme, "sans", color, { weight: "bold" }), - size: 14, - }, + text: text(theme, "sans", color, { size: "sm" }), + highlightText: text(theme, "sans", color, { + size: "sm", + weight: "bold", + }), }, }; } @@ -75,7 +72,7 @@ export default function editor(theme: Theme) { item: autocompleteItem, hoveredItem: { ...autocompleteItem, - background: backgroundColor(theme, 100, "hover"), + background: backgroundColor(theme, 100, "hovered"), }, margin: { left: -14, @@ -98,34 +95,25 @@ export default function editor(theme: Theme) { top: true, }), code: { - ...text(theme, "mono", "muted"), - size: 14, + ...text(theme, "mono", "muted", { size: "sm" }), margin: { left: 10, }, }, message: { - highlightText: { - ...text(theme, "sans", "primary"), - size: 14, + highlightText: text(theme, "sans", "primary", { + size: "sm", weight: "bold", - }, - text: { - ...text(theme, "sans", "secondary"), - size: 14, - }, + }), + text: text(theme, "sans", "secondary", { size: "sm" }), }, }, diagnosticPathHeader: { background: theme.editor.line.active, textScaleFactor: 0.857, - filename: { - ...text(theme, "mono", "primary"), - size: 14, - }, + filename: text(theme, "mono", "primary", { size: "sm" }), path: { - ...text(theme, "mono", "muted"), - size: 14, + ...text(theme, "mono", "muted", { size: "sm" }), margin: { left: 12, }, diff --git a/styles/project-panel.ts b/styles/project-panel.ts new file mode 100644 index 0000000000000000000000000000000000000000..343e11b96b6e8adb3c6bd223a71de3e6d7d05f40 --- /dev/null +++ b/styles/project-panel.ts @@ -0,0 +1,32 @@ +import { panel } from "./app"; +import { backgroundColor, iconColor, text, TextColor } from "./components"; +import Theme from "./theme"; +import { Color } from "./lib"; + +export default function projectPanel(theme: Theme) { + function entry(theme: Theme, textColor: TextColor, background?: Color) { + return { + height: 22, + background, + iconColor: iconColor(theme, "muted"), + iconSize: 8, + iconSpacing: 8, + text: text(theme, "mono", textColor), + }; + } + + return { + ...panel, + entry: entry(theme, "secondary"), + hoveredEntry: entry( + theme, + "secondary", + backgroundColor(theme, 300, "hovered") + ), + selectedEntry: entry(theme, "primary"), + hoveredSelectedEntry: entry(theme, "primary", "hovered"), + padding: { + top: 6, + }, + }; +} diff --git a/styles/theme.ts b/styles/theme.ts index 5220c962c9d2032d35b15e32d12547f92d4c4679..27f578f4366bacae8fdc5d4dc366375532e7f2b8 100644 --- a/styles/theme.ts +++ b/styles/theme.ts @@ -1,5 +1,3 @@ -import { colorRamp } from "./lib"; - export type Color = string; export type Weight = | "thin" @@ -36,7 +34,7 @@ export interface BackgroundColor { base: { value: Color; }; - hover: { + hovered: { value: Color; }; active: { From 70b15e4c909b8723442b6d6ec1dc61d2aab2803f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 30 Mar 2022 18:45:34 -0600 Subject: [PATCH 45/68] Convert chat panel --- styles/app.ts | 112 +------------------------------------------ styles/chat-panel.ts | 108 +++++++++++++++++++++++++++++++++++++++++ styles/components.ts | 8 +++- 3 files changed, 116 insertions(+), 112 deletions(-) create mode 100644 styles/chat-panel.ts diff --git a/styles/app.ts b/styles/app.ts index ae0f0717bb5dc13e20db348d36bdeb1d562e0885..5f2993d30a68cad4410992387bf65a6d76c72a34 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -4,6 +4,7 @@ import workspace from "./workspace"; import editor from "./editor"; import Theme from "./theme"; import projectPanel from "./project-panel"; +import chatPanel from "./chat-panel"; export const panel = { padding: { top: 12, left: 12, bottom: 12, right: 12 }, @@ -30,116 +31,7 @@ export default function app(theme: Theme): Object { }, }, projectPanel: projectPanel(theme), - chatPanel: { - extends: "$panel", - channelName: { - extends: "$text.primary", - weight: "bold", - }, - channelNameHash: { - text: "$text.muted", - padding: { - right: 8, - }, - }, - channelSelect: { - activeItem: { - extends: "$chatPanel.channel_select.item", - name: "$text.primary", - }, - header: { - extends: "$chat_panel.channel_select.activeItem", - padding: { - bottom: 4, - left: 0, - }, - }, - hoveredActiveItem: { - extends: "$chatPanel.channelSelect.hoveredItem", - name: "$text.primary", - }, - hoveredItem: { - background: "$state.hover", - cornerRadius: 6, - extends: "$chat_panel.channelSelect.item", - }, - item: { - name: "$text.secondary", - padding: 4, - hash: { - extends: "$text.muted", - margin: { - right: 8, - }, - }, - }, - menu: { - background: "$surface.500", - cornerRadius: 6, - padding: 4, - border: { - color: "$border.primary", - width: 1, - }, - shadow: { - blur: 16, - color: "$shadow.0", - offset: [0, 2], - }, - }, - }, - hoveredSignInPrompt: { - color: "$text.secondary.color", - extends: "$chatPanel.signInPrompt", - }, - inputEditor: { - background: backgroundColor(theme, 300), - cornerRadius: 6, - placeholderText: "$text.muted", - selection: "$selection.host", - text: "$text.primary", - border: { - color: "$border.primary", - width: 1, - }, - padding: { - bottom: 7, - left: 8, - right: 8, - top: 7, - }, - }, - message: { - body: "$text.secondary", - timestamp: "$text.muted", - padding: { - bottom: 6, - }, - sender: { - extends: "$text.primary", - weight: "bold", - margin: { - right: 8, - }, - }, - }, - pendingMessage: { - extends: "$chatPanel.message", - body: { - color: "$text.muted.color", - }, - sender: { - color: "$text.muted.color", - }, - timestamp: { - color: "$text.muted.color", - }, - }, - signInPrompt: { - extends: "$text.primary", - underline: true, - }, - }, + chatPanel: chatPanel(theme), contactsPanel: { extends: "$panel", hostRowHeight: 28, diff --git a/styles/chat-panel.ts b/styles/chat-panel.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6bf0148ea4c5d9345c29d5df94c978588e4fd0d --- /dev/null +++ b/styles/chat-panel.ts @@ -0,0 +1,108 @@ +import { panel } from "./app"; +import { + backgroundColor, + border, + player, + shadow, + text, + TextColor, +} from "./components"; +import Theme from "./theme"; + +export default function chatPanel(theme: Theme) { + function channelSelectItem( + theme: Theme, + textColor: TextColor, + hovered: boolean + ) { + return { + name: text(theme, "sans", textColor), + padding: 4, + hash: { + ...text(theme, "sans", "muted"), + margin: { + right: 8, + }, + }, + background: hovered ? backgroundColor(theme, 300, "hovered") : undefined, + cornerRadius: hovered ? 6 : 0, + }; + } + + const message = { + body: text(theme, "sans", "secondary"), + timestamp: text(theme, "sans", "muted"), + padding: { + bottom: 6, + }, + sender: { + ...text(theme, "sans", "primary", { weight: "bold" }), + margin: { + right: 8, + }, + }, + }; + + return { + ...panel, + channelName: text(theme, "sans", "primary", { weight: "bold" }), + channelNameHash: { + ...text(theme, "sans", "muted"), + padding: { + right: 8, + }, + }, + channelSelect: { + header: { + ...channelSelectItem(theme, "primary", false), + padding: { + bottom: 4, + left: 0, + }, + }, + item: channelSelectItem(theme, "secondary", false), + hoveredItem: channelSelectItem(theme, "secondary", true), + activeItem: channelSelectItem(theme, "primary", false), + hoveredActiveItem: channelSelectItem(theme, "primary", true), + menu: { + background: backgroundColor(theme, 500), + cornerRadius: 6, + padding: 4, + border: border(theme, "primary"), + shadow: shadow(theme), + }, + }, + signInPrompt: text(theme, "sans", "secondary", { underline: true }), + hoveredSignInPrompt: text(theme, "sans", "primary", { underline: true }), + message, + pendingMessage: { + ...message, + body: { + ...message.body, + color: theme.textColor.muted.value, + }, + sender: { + ...message.sender, + color: theme.textColor.muted.value, + }, + timestamp: { + ...message.timestamp, + color: theme.textColor.muted.value, + }, + }, + inputEditor: { + background: backgroundColor(theme, 300), + cornerRadius: 6, + text: text(theme, "mono", "primary"), + placeholderText: text(theme, "mono", "muted"), + selection: player(theme, 1).selection, + border: border(theme, "primary"), + padding: { + bottom: 7, + left: 8, + right: 8, + top: 7, + }, + }, + }; +} diff --git a/styles/components.ts b/styles/components.ts index 14becaf2af30e94d4c6d3a0250b0e3f3aab52faf..28d883927bb8f7d6f333a1cf8e45c1149910ba63 100644 --- a/styles/components.ts +++ b/styles/components.ts @@ -9,7 +9,11 @@ export function text( theme: Theme, fontFamily: keyof typeof core.fontFamily, color: TextColor, - properties?: { size?: keyof typeof core["fontSize"]; weight?: Weight } + properties?: { + size?: keyof typeof core["fontSize"]; + weight?: Weight; + underline?: boolean; + } ) { const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md"; const size = core.fontSize[sizeKey].value; @@ -74,7 +78,7 @@ export function backgroundColor( return theme.backgroundColor[name][state || "base"].value; } -export function shadow(theme) { +export function shadow(theme: Theme) { return { blur: 16, color: chroma("black").alpha(theme.shadowAlpha.value).hex(), From d88e20477df2cffa2b10b64dc65ce68066fd40f7 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 01:38:18 -0400 Subject: [PATCH 46/68] Update app.ts, editor.ts --- styles/app.ts | 63 +++++++++++++++++++------------------------- styles/components.ts | 4 +++ styles/editor.ts | 4 +-- styles/theme.ts | 12 +++++++++ styles/workspace.ts | 4 +-- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/styles/app.ts b/styles/app.ts index 5f2993d30a68cad4410992387bf65a6d76c72a34..11e476baf73ec97e010288edcad2ce730299833b 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -1,10 +1,10 @@ -import { backgroundColor, text } from "./components"; -import selectorModal from "./selector-modal"; -import workspace from "./workspace"; +import chatPanel from "./chat-panel"; +import { backgroundColor, border, borderColor, player, text } from "./components"; import editor from "./editor"; -import Theme from "./theme"; import projectPanel from "./project-panel"; -import chatPanel from "./chat-panel"; +import selectorModal from "./selector-modal"; +import Theme from "./theme"; +import workspace from "./workspace"; export const panel = { padding: { top: 12, left: 12, bottom: 12, right: 12 }, @@ -35,27 +35,27 @@ export default function app(theme: Theme): Object { contactsPanel: { extends: "$panel", hostRowHeight: 28, - treeBranchColor: "$surface.100", + treeBranchColor: borderColor(theme, "muted"), treeBranchWidth: 1, hostAvatar: { cornerRadius: 10, width: 18, }, hostUsername: { - extends: "$text.primary", + ...text(theme, "mono", "muted"), padding: { left: 8, }, }, hoveredSharedProject: { - background: "$state.hover", - cornerRadius: 6, extends: "$contacts_panel.sharedProject", + background: theme.editor.line.active.value, + cornerRadius: 6, }, hoveredUnsharedProject: { - background: "$state.hover", - cornerRadius: 6, extends: "$contacts_panel.unsharedProject", + background: theme.editor.line.active.value, + cornerRadius: 6, }, project: { guestAvatarSpacing: 4, @@ -65,7 +65,7 @@ export default function app(theme: Theme): Object { width: 14, }, name: { - extends: "$text.secondary", + extends: text(theme, "mono", "secondary"), margin: { right: 6, }, @@ -77,7 +77,7 @@ export default function app(theme: Theme): Object { sharedProject: { extends: "$contactsPanel.project", name: { - color: "$text.primary.color", + color: text(theme, "mono", "primary"), }, }, unsharedProject: { @@ -86,28 +86,25 @@ export default function app(theme: Theme): Object { }, search: { background: backgroundColor(theme, 300), - matchBackground: "$state.highlightedLine", + matchBackground: theme.editor.highlight.match, tabIconSpacing: 4, tabIconWidth: 14, activeHoveredOptionButton: { - background: "$surface.100", extends: "$search.option_button", + background: backgroundColor(theme, 100), }, activeOptionButton: { - background: "$surface.100", extends: "$search.option_button", + background: backgroundColor(theme, 100), }, editor: { - background: "$surface.500", + background: backgroundColor(theme, 500), cornerRadius: 6, maxWidth: 400, - placeholderText: "$text.muted", - selection: "$selection.host", - text: "$text.primary", - border: { - color: "$border.primary", - width: 1, - }, + placeholderText: text(theme, "mono", "placeholder"), + selection: player(theme, 1).selection, + text: text(theme, "mono", "primary"), + border: border(theme, "primary"), margin: { bottom: 5, left: 5, @@ -122,28 +119,22 @@ export default function app(theme: Theme): Object { }, }, hoveredOptionButton: { - background: "$surface.100", extends: "$search.optionButton", + background: backgroundColor(theme, 100), }, invalidEditor: { extends: "$search.editor", - border: { - color: "$status.bad", - width: 1, - }, + border: border(theme, "error"), }, matchIndex: { - extends: "$text.secondary", + ...text(theme, "mono", "secondary"), padding: 6, }, optionButton: { + ...text(theme, "mono", "secondary"), background: backgroundColor(theme, 300), cornerRadius: 6, - extends: "$text.secondary", - border: { - color: "$border.primary", - width: 1, - }, + border: border(theme, "primary"), margin: { left: 1, right: 1, @@ -162,7 +153,7 @@ export default function app(theme: Theme): Object { }, }, resultsStatus: { - extends: "$text.primary", + ...text(theme, "mono", "primary"), size: 18, }, }, diff --git a/styles/components.ts b/styles/components.ts index 28d883927bb8f7d6f333a1cf8e45c1149910ba63..c8b2f87638a004365596f0ec11bab644580ed255 100644 --- a/styles/components.ts +++ b/styles/components.ts @@ -47,6 +47,10 @@ export function border( }; } +export function borderColor(theme: Theme, color: keyof Theme["borderColor"]) { + return theme.borderColor[color].value; +} + export function iconColor(theme: Theme, color: keyof Theme["iconColor"]) { return theme.iconColor[color].value; } diff --git a/styles/editor.ts b/styles/editor.ts index ea7012d2092ebd0d7df324762f4703693b32a89d..a27464eee2182ecfb0633623ff4e773cfb85b35d 100644 --- a/styles/editor.ts +++ b/styles/editor.ts @@ -4,7 +4,7 @@ import { iconColor, player, text, - TextColor, + TextColor } from "./components"; import Theme from "./theme"; @@ -89,7 +89,7 @@ export default function editor(theme: Theme) { diagnosticHeader: { background: theme.editor.background.value, iconWidthFactor: 1.5, - textScaleFactor: 0.857, + textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. border: border(theme, "secondary", { bottom: true, top: true, diff --git a/styles/theme.ts b/styles/theme.ts index 27f578f4366bacae8fdc5d4dc366375532e7f2b8..9d297d552d38b21154a77b2eed22d49a1ce2a247 100644 --- a/styles/theme.ts +++ b/styles/theme.ts @@ -71,6 +71,18 @@ export default interface Theme { active: { value: Color; }; + ok: { + value: Color; + }; + error: { + value: Color; + }; + warning: { + value: Color; + }; + info: { + value: Color; + }; }; textColor: { primary: { diff --git a/styles/workspace.ts b/styles/workspace.ts index 5ecb3a378c8d1a5acedc5100203c9b9306e36dca..1a50fe9ee1c248de6d48a9521efa9f9cc8f82fbb 100644 --- a/styles/workspace.ts +++ b/styles/workspace.ts @@ -42,8 +42,8 @@ export default function workspace(theme: Theme) { }; const sidebarItem = { - height: "$workspace.tab.height", - iconColor: "$text.muted.color", + height: 32, + iconColor: iconColor(theme, "secondary"), iconSize: 18, }; const sidebar = { From c008e65de6cfdae9b1a3f3fc73c53aeef1f790c6 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 11:27:02 -0400 Subject: [PATCH 47/68] Extract `search` from `app` - Also update border to use borderColor( ) --- styles/app.ts | 79 +++---------------------------------------- styles/components.ts | 2 +- styles/search.ts | 80 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 76 deletions(-) create mode 100644 styles/search.ts diff --git a/styles/app.ts b/styles/app.ts index 11e476baf73ec97e010288edcad2ce730299833b..a65442db0737630f77d1de92d921d934ed4a8804 100644 --- a/styles/app.ts +++ b/styles/app.ts @@ -1,7 +1,8 @@ import chatPanel from "./chat-panel"; -import { backgroundColor, border, borderColor, player, text } from "./components"; +import { backgroundColor, borderColor, text } from "./components"; import editor from "./editor"; import projectPanel from "./project-panel"; +import search from "./search"; import selectorModal from "./selector-modal"; import Theme from "./theme"; import workspace from "./workspace"; @@ -33,7 +34,7 @@ export default function app(theme: Theme): Object { projectPanel: projectPanel(theme), chatPanel: chatPanel(theme), contactsPanel: { - extends: "$panel", + ...panel, hostRowHeight: 28, treeBranchColor: borderColor(theme, "muted"), treeBranchWidth: 1, @@ -84,78 +85,6 @@ export default function app(theme: Theme): Object { extends: "$contactsPanel.project", }, }, - search: { - background: backgroundColor(theme, 300), - matchBackground: theme.editor.highlight.match, - tabIconSpacing: 4, - tabIconWidth: 14, - activeHoveredOptionButton: { - extends: "$search.option_button", - background: backgroundColor(theme, 100), - }, - activeOptionButton: { - extends: "$search.option_button", - background: backgroundColor(theme, 100), - }, - editor: { - background: backgroundColor(theme, 500), - cornerRadius: 6, - maxWidth: 400, - placeholderText: text(theme, "mono", "placeholder"), - selection: player(theme, 1).selection, - text: text(theme, "mono", "primary"), - border: border(theme, "primary"), - margin: { - bottom: 5, - left: 5, - right: 5, - top: 5, - }, - padding: { - bottom: 3, - left: 13, - right: 13, - top: 3, - }, - }, - hoveredOptionButton: { - extends: "$search.optionButton", - background: backgroundColor(theme, 100), - }, - invalidEditor: { - extends: "$search.editor", - border: border(theme, "error"), - }, - matchIndex: { - ...text(theme, "mono", "secondary"), - padding: 6, - }, - optionButton: { - ...text(theme, "mono", "secondary"), - background: backgroundColor(theme, 300), - cornerRadius: 6, - border: border(theme, "primary"), - margin: { - left: 1, - right: 1, - }, - padding: { - bottom: 1, - left: 6, - right: 6, - top: 1, - }, - }, - optionButtonGroup: { - padding: { - left: 2, - right: 2, - }, - }, - resultsStatus: { - ...text(theme, "mono", "primary"), - size: 18, - }, - }, + search: search(theme), }; } diff --git a/styles/components.ts b/styles/components.ts index c8b2f87638a004365596f0ec11bab644580ed255..590c1b5eea9f6779dee0c2697a781d36b3edee60 100644 --- a/styles/components.ts +++ b/styles/components.ts @@ -41,7 +41,7 @@ export function border( options?: BorderOptions ) { return { - color: theme.borderColor[color].value, + color: borderColor(theme, color), width: 1, ...options, }; diff --git a/styles/search.ts b/styles/search.ts new file mode 100644 index 0000000000000000000000000000000000000000..ced2266ea73480da11f880d4c56b4a65aa83f12c --- /dev/null +++ b/styles/search.ts @@ -0,0 +1,80 @@ +import { backgroundColor, border, player, text } from "./components"; +import Theme from "./theme"; + +export default function search(theme: Theme) { + const optionButton = { + ...text(theme, "mono", "secondary"), + background: backgroundColor(theme, 300), + cornerRadius: 6, + border: border(theme, "primary"), + margin: { + left: 1, + right: 1, + }, + padding: { + bottom: 1, + left: 6, + right: 6, + top: 1, + }, + }; + + return { + background: backgroundColor(theme, 300), + matchBackground: theme.editor.highlight.match, + tabIconSpacing: 4, + tabIconWidth: 14, + activeHoveredOptionButton: { + ...optionButton, + background: backgroundColor(theme, 100), + }, + activeOptionButton: { + ...optionButton, + background: backgroundColor(theme, 100), + }, + editor: { + background: backgroundColor(theme, 500), + cornerRadius: 6, + maxWidth: 400, + placeholderText: text(theme, "mono", "placeholder"), + selection: player(theme, 1).selection, + text: text(theme, "mono", "primary"), + border: border(theme, "primary"), + margin: { + bottom: 5, + left: 5, + right: 5, + top: 5, + }, + padding: { + bottom: 3, + left: 13, + right: 13, + top: 3, + }, + }, + hoveredOptionButton: { + ...optionButton, + background: backgroundColor(theme, 100), + }, + invalidEditor: { + extends: "$search.editor", + border: border(theme, "error"), + }, + matchIndex: { + ...text(theme, "mono", "secondary"), + padding: 6, + }, + optionButton, + optionButtonGroup: { + padding: { + left: 2, + right: 2, + }, + }, + resultsStatus: { + ...text(theme, "mono", "primary"), + size: 18, + }, + }; +} From ae8b610d85aac1d46782113ee1ad38a0650279af Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 19:10:44 -0400 Subject: [PATCH 48/68] WIP: Scaffold tokens in dark.ts, no real values yet. --- styles/dark.ts | 438 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 styles/dark.ts diff --git a/styles/dark.ts b/styles/dark.ts new file mode 100644 index 0000000000000000000000000000000000000000..019f50e40cec8ede5e62d2db37e97e691fbce8d6 --- /dev/null +++ b/styles/dark.ts @@ -0,0 +1,438 @@ +import Theme from "./theme"; + +export default function dark(): Theme { + return { + backgroundColor: { + 100: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + 300: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + 500: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + ok: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + error: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + warning: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + info: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + }, + borderColor: { + primary: { + value: "#000000", + }, + secondary: { + value: "#000000", + }, + muted: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + active: { + value: "#000000", + }, + ok: { + value: "#000000", + }, + error: { + value: "#000000", + }, + warning: { + value: "#000000", + }, + info: { + value: "#000000", + }, + }, + textColor: { + primary: { + value: "#000000", + }, + secondary: { + value: "#000000", + }, + muted: { + value: "#000000", + }, + placeholder: { + value: "#000000", + }, + active: { + value: "#000000", + }, + feature: { + value: "#000000", + }, + ok: { + value: "#000000", + }, + error: { + value: "#000000", + }, + warning: { + value: "#000000", + }, + info: { + value: "#000000", + }, + }, + iconColor: { + primary: { + value: "#000000", + }, + secondary: { + value: "#000000", + }, + muted: { + value: "#000000", + }, + placeholder: { + value: "#000000", + }, + active: { + value: "#000000", + }, + feature: { + value: "#000000", + }, + ok: { + value: "#000000", + }, + error: { + value: "#000000", + }, + warning: { + value: "#000000", + }, + info: { + value: "#000000", + }, + }, + editor: { + background: { + value: "#000000", + }, + indent_guide: { + value: "#000000", + }, + indent_guide_active: { + value: "#000000", + }, + line: { + active: { + value: "#000000", + }, + highlighted: { + value: "#000000", + }, + inserted: { + value: "#000000", + }, + deleted: { + value: "#000000", + }, + modified: { + value: "#000000", + }, + }, + highlight: { + selection: { + value: "#000000", + }, + occurrence: { + value: "#000000", + }, + activeOccurrence: { + value: "#000000", + }, + matchingBracket: { + value: "#000000", + }, + match: { + value: "#000000", + }, + activeMatch: { + value: "#000000", + }, + related: { + value: "#000000", + }, + }, + gutter: { + primary: { + value: "#000000", + }, + active: { + value: "#000000", + }, + }, + }, + + syntax: { + primary: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + comment: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + punctuation: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + constant: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + keyword: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + function: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + type: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + variant: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + property: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + enum: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + operator: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + string: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + number: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + boolean: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + predictive: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + }, + player: { + 1: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 2: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 3: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 4: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 5: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 6: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 7: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + 8: { + baseColor: { + value: "#000000", + }, + cursorColor: { + value: "#000000", + }, + selectionColor: { + value: "#000000", + }, + borderColor: { + value: "#000000", + }, + }, + }, + shadowAlpha: { + value: 0.32, + }, + }; +} \ No newline at end of file From 083c1f7c0ea8fe94a794d31f3a583566fc8db905 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 20:32:47 -0400 Subject: [PATCH 49/68] WIP for keith --- styles/dark.ts | 880 +++++++++++++++++++++++++------------------------ 1 file changed, 449 insertions(+), 431 deletions(-) diff --git a/styles/dark.ts b/styles/dark.ts index 019f50e40cec8ede5e62d2db37e97e691fbce8d6..efd2d3b8a49b1b43c53b8ee782d13615c0f3e0d2 100644 --- a/styles/dark.ts +++ b/styles/dark.ts @@ -1,438 +1,456 @@ +import core from "./core"; import Theme from "./theme"; -export default function dark(): Theme { - return { - backgroundColor: { - 100: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - 300: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - 500: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - ok: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - error: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - warning: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, - info: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - }, +const backgroundColor = { + 100: { + base: { + value: core.color.neutral[999].value, }, - borderColor: { - primary: { - value: "#000000", - }, - secondary: { - value: "#000000", - }, - muted: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - active: { - value: "#000000", - }, - ok: { - value: "#000000", - }, - error: { - value: "#000000", - }, - warning: { - value: "#000000", - }, - info: { - value: "#000000", - }, - }, - textColor: { - primary: { - value: "#000000", - }, - secondary: { - value: "#000000", - }, - muted: { - value: "#000000", - }, - placeholder: { - value: "#000000", - }, - active: { - value: "#000000", - }, - feature: { - value: "#000000", - }, - ok: { - value: "#000000", - }, - error: { - value: "#000000", - }, - warning: { - value: "#000000", - }, - info: { - value: "#000000", - }, - }, - iconColor: { - primary: { - value: "#000000", - }, - secondary: { - value: "#000000", - }, - muted: { - value: "#000000", - }, - placeholder: { - value: "#000000", - }, - active: { - value: "#000000", - }, - feature: { - value: "#000000", - }, - ok: { - value: "#000000", - }, - error: { - value: "#000000", - }, - warning: { - value: "#000000", - }, - info: { - value: "#000000", - }, - }, - editor: { - background: { - value: "#000000", - }, - indent_guide: { - value: "#000000", - }, - indent_guide_active: { - value: "#000000", - }, - line: { - active: { - value: "#000000", - }, - highlighted: { - value: "#000000", - }, - inserted: { - value: "#000000", - }, - deleted: { - value: "#000000", - }, - modified: { - value: "#000000", - }, - }, - highlight: { - selection: { - value: "#000000", - }, - occurrence: { - value: "#000000", - }, - activeOccurrence: { - value: "#000000", - }, - matchingBracket: { - value: "#000000", - }, - match: { - value: "#000000", - }, - activeMatch: { - value: "#000000", - }, - related: { - value: "#000000", - }, - }, - gutter: { - primary: { - value: "#000000", - }, - active: { - value: "#000000", - }, - }, + hovered: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + focused: { + value: core.color.neutral[999].value, + }, + }, + 300: { + base: { + value: core.color.neutral[999].value, + }, + hovered: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + focused: { + value: core.color.neutral[999].value, + }, + }, + 500: { + base: { + value: core.color.neutral[999].value, + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + ok: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + error: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + warning: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + info: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, +}; - syntax: { - primary: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - comment: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - punctuation: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - constant: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - keyword: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - function: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - type: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - variant: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - property: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - enum: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - operator: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - string: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - number: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - boolean: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - predictive: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - }, - player: { - 1: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 2: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 3: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 4: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 5: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 6: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 7: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - 8: { - baseColor: { - value: "#000000", - }, - cursorColor: { - value: "#000000", - }, - selectionColor: { - value: "#000000", - }, - borderColor: { - value: "#000000", - }, - }, - }, - shadowAlpha: { - value: 0.32, +const borderColor = { + primary: { + value: "#000000", + }, + secondary: { + value: "#000000", + }, + muted: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + active: { + value: "#000000", + }, + ok: { + value: "#000000", + }, + error: { + value: "#000000", + }, + warning: { + value: "#000000", + }, + info: { + value: "#000000", + }, +}; + +const textColor = { + primary: { + value: core.color.neutral[150].value, + }, + secondary: { + value: core.color.neutral[350].value, + }, + muted: { + value: core.color.neutral[550].value, + }, + placeholder: { + value: core.color.neutral[750].value, + }, + active: { + value: core.color.neutral[0].value, + }, + feature: { + //TODO: (design) define feature and it's correct value + value: core.color.sky[500].value, + }, + ok: { + value: core.color.green[600].value, + }, + error: { + value: core.color.red[400].value, + }, + warning: { + value: core.color.amber[300].value, + }, + info: { + value: core.color.blue[500].value, + }, +}; + +const iconColor = { + primary: { + value: core.color.neutral[300].value, + }, + secondary: { + value: core.color.neutral[500].value, + }, + muted: { + value: core.color.neutral[600].value, + }, + placeholder: { + value: core.color.neutral[700].value, + }, + active: { + value: core.color.neutral[50].value, + }, + feature: { + //TODO: (design) define feature and it's correct value + value: core.color.sky[500].value, + }, + ok: { + value: core.color.green[600].value, + }, + error: { + value: core.color.red[400].value, + }, + warning: { + value: core.color.amber[300].value, + }, + info: { + value: core.color.blue[500].value, + }, +}; + +const editor = { + background: { + value: backgroundColor[500].base.value, + }, + indent_guide: { + value: core.color.neutral[999].value, + }, + indent_guide_active: { + value: core.color.neutral[999].value, + }, + line: { + active: { + value: core.color.neutral[999].value, + }, + highlighted: { + value: core.color.neutral[999].value, + }, + inserted: { + value: core.color.neutral[999].value, + }, + deleted: { + value: core.color.neutral[999].value, }, + modified: { + value: core.color.neutral[999].value, + }, + }, + highlight: { + selection: { + value: core.color.neutral[999].value, + }, + occurrence: { + value: core.color.neutral[999].value, + }, + activeOccurrence: { + value: core.color.neutral[999].value, + }, + matchingBracket: { + value: core.color.neutral[999].value, + }, + match: { + value: core.color.neutral[999].value, + }, + activeMatch: { + value: core.color.neutral[999].value, + }, + related: { + value: core.color.neutral[999].value, + }, + }, + gutter: { + primary: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + }, +}; + +const syntax = { + primary: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + comment: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + punctuation: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + constant: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + keyword: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + function: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + type: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + variant: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + property: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + enum: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + operator: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + string: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + number: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + boolean: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, + predictive: { + color: { value: "000000" }, + weight: { value: "normal" }, + }, +}; + +const player = { + 1: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 2: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 3: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 4: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 5: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 6: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 7: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 8: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, +}; + +const shadowAlpha = { + value: 0.32, +}; + +export default function dark(): Theme { + return { + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, }; -} \ No newline at end of file +} From 210eb2f6b141cfdbf7bb47a0cc74a25a7925a2ad Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 17:51:25 -0700 Subject: [PATCH 50/68] wip --- message.txt | 1672 ++++++++++++++++++++++++++++++++++++++++++++++++ styles/dark.ts | 780 +++++++++++----------- 2 files changed, 2063 insertions(+), 389 deletions(-) create mode 100644 message.txt diff --git a/message.txt b/message.txt new file mode 100644 index 0000000000000000000000000000000000000000..f086360d37f8ee060cb030b5f2026d7a81f4864c --- /dev/null +++ b/message.txt @@ -0,0 +1,1672 @@ +{ + "core": { + "color": { + "neutral": { + "0": { + "value": "#FFFFFF", + "type": "color" + }, + "50": { + "value": "#F8F8F8", + "type": "color" + }, + "100": { + "value": "#F0F0F0", + "type": "color" + }, + "150": { + "value": "#E1E1E1", + "type": "color" + }, + "200": { + "value": "#D2D2D2", + "type": "color" + }, + "250": { + "value": "#C3C3C3", + "type": "color" + }, + "300": { + "value": "#B4B4B4", + "type": "color" + }, + "350": { + "value": "#A5A5A5", + "type": "color" + }, + "400": { + "value": "#969696", + "type": "color" + }, + "450": { + "value": "#878787", + "type": "color" + }, + "500": { + "value": "#787878", + "type": "color" + }, + "550": { + "value": "#696969", + "type": "color" + }, + "600": { + "value": "#5A5A5A", + "type": "color" + }, + "650": { + "value": "#4B4B4B", + "type": "color" + }, + "700": { + "value": "#3C3C3C", + "type": "color" + }, + "750": { + "value": "#262626", + "type": "color" + }, + "800": { + "value": "#1E1E1E", + "type": "color" + }, + "850": { + "value": "#0F0F0F", + "type": "color" + }, + "900": { + "value": "#000000", + "type": "color" + } + }, + "steel": { + "0": { + "value": "#F8FAFC", + "type": "color" + }, + "100": { + "value": "#F1F5F9", + "type": "color" + }, + "200": { + "value": "#E2E8F0", + "type": "color" + }, + "300": { + "value": "#CBD5E1", + "type": "color" + }, + "400": { + "value": "#94A3BA", + "type": "color" + }, + "500": { + "value": "#64748B", + "type": "color" + }, + "600": { + "value": "#475569", + "type": "color" + }, + "700": { + "value": "#334155", + "type": "color" + }, + "800": { + "value": "#1E293B", + "type": "color" + }, + "900": { + "value": "#0F172A", + "type": "color" + } + }, + "gray": { + "0": { + "value": "#FAFAFA", + "type": "color" + }, + "100": { + "value": "#F4F4F5", + "type": "color" + }, + "200": { + "value": "#E4E4E7", + "type": "color" + }, + "300": { + "value": "#D4D4D8", + "type": "color" + }, + "400": { + "value": "#A1A1AA", + "type": "color" + }, + "500": { + "value": "#71717A", + "type": "color" + }, + "600": { + "value": "#52525B", + "type": "color" + }, + "700": { + "value": "#3F3F46", + "type": "color" + }, + "800": { + "value": "#27272A", + "type": "color" + }, + "900": { + "value": "#18181B", + "type": "color" + } + }, + "rose": { + "0": { + "value": "#FFF1F2", + "type": "color" + }, + "100": { + "value": "#FFE4E6", + "type": "color" + }, + "200": { + "value": "#FECDD3", + "type": "color" + }, + "300": { + "value": "#FDA4AF", + "type": "color" + }, + "400": { + "value": "#FB7185", + "type": "color" + }, + "500": { + "value": "#F43F5E", + "type": "color" + }, + "600": { + "value": "#E11D48", + "type": "color" + }, + "700": { + "value": "#BE123C", + "type": "color" + }, + "800": { + "value": "#9F1239", + "type": "color" + }, + "900": { + "value": "#881337", + "type": "color" + } + }, + "red": { + "0": { + "value": "#FEF2F2", + "type": "color" + }, + "100": { + "value": "#FEE2E2", + "type": "color" + }, + "200": { + "value": "#FECACA", + "type": "color" + }, + "300": { + "value": "#FCA5A5", + "type": "color" + }, + "400": { + "value": "#F87171", + "type": "color" + }, + "500": { + "value": "#EF4444", + "type": "color" + }, + "600": { + "value": "#DC2626", + "type": "color" + }, + "700": { + "value": "#B91C1C", + "type": "color" + }, + "800": { + "value": "#991B1B", + "type": "color" + }, + "900": { + "value": "#7F1D1D", + "type": "color" + } + }, + "orange": { + "0": { + "value": "#FFF7ED", + "type": "color" + }, + "100": { + "value": "#FFEDD5", + "type": "color" + }, + "200": { + "value": "#FED7AA", + "type": "color" + }, + "300": { + "value": "#FDBA74", + "type": "color" + }, + "400": { + "value": "#FB923C", + "type": "color" + }, + "500": { + "value": "#F97316", + "type": "color" + }, + "600": { + "value": "#EA580C", + "type": "color" + }, + "700": { + "value": "#C2410C", + "type": "color" + }, + "800": { + "value": "#9A3412", + "type": "color" + }, + "900": { + "value": "#7C2D12", + "type": "color" + } + }, + "amber": { + "0": { + "value": "#FFFBEB", + "type": "color" + }, + "100": { + "value": "#FEF3C7", + "type": "color" + }, + "200": { + "value": "#FDE68A", + "type": "color" + }, + "300": { + "value": "#FCD34D", + "type": "color" + }, + "400": { + "value": "#FBBF24", + "type": "color" + }, + "500": { + "value": "#F59E0B", + "type": "color" + }, + "600": { + "value": "#D97706", + "type": "color" + }, + "700": { + "value": "#B45309", + "type": "color" + }, + "800": { + "value": "#92400E", + "type": "color" + }, + "900": { + "value": "#78350F", + "type": "color" + } + }, + "yellow": { + "0": { + "value": "#FEFCE8", + "type": "color" + }, + "100": { + "value": "#FEF9C3", + "type": "color" + }, + "200": { + "value": "#FEF08A", + "type": "color" + }, + "300": { + "value": "#FDE047", + "type": "color" + }, + "400": { + "value": "#FACC15", + "type": "color" + }, + "500": { + "value": "#EAB308", + "type": "color" + }, + "600": { + "value": "#CA8A04", + "type": "color" + }, + "700": { + "value": "#A16207", + "type": "color" + }, + "800": { + "value": "#854D0E", + "type": "color" + }, + "900": { + "value": "#713F12", + "type": "color" + } + }, + "lime": { + "0": { + "value": "#F7FEE7", + "type": "color" + }, + "100": { + "value": "#ECFCCB", + "type": "color" + }, + "200": { + "value": "#D9F99D", + "type": "color" + }, + "300": { + "value": "#BEF264", + "type": "color" + }, + "400": { + "value": "#A3E635", + "type": "color" + }, + "500": { + "value": "#84CC16", + "type": "color" + }, + "600": { + "value": "#65A30D", + "type": "color" + }, + "700": { + "value": "#4D7C0F", + "type": "color" + }, + "800": { + "value": "#3F6212", + "type": "color" + }, + "900": { + "value": "#365314", + "type": "color" + } + }, + "green": { + "0": { + "value": "#F0FDF4", + "type": "color" + }, + "100": { + "value": "#DCFCE7", + "type": "color" + }, + "200": { + "value": "#BBF7D0", + "type": "color" + }, + "300": { + "value": "#86EFAC", + "type": "color" + }, + "400": { + "value": "#4ADE80", + "type": "color" + }, + "500": { + "value": "#22C55E", + "type": "color" + }, + "600": { + "value": "#16A34A", + "type": "color" + }, + "700": { + "value": "#15803D", + "type": "color" + }, + "800": { + "value": "#166534", + "type": "color" + }, + "900": { + "value": "#14532D", + "type": "color" + } + }, + "emerald": { + "0": { + "value": "#ECFDF5", + "type": "color" + }, + "100": { + "value": "#D1FAE5", + "type": "color" + }, + "200": { + "value": "#A7F3D0", + "type": "color" + }, + "300": { + "value": "#6EE7B7", + "type": "color" + }, + "400": { + "value": "#34D399", + "type": "color" + }, + "500": { + "value": "#10B981", + "type": "color" + }, + "600": { + "value": "#059669", + "type": "color" + }, + "700": { + "value": "#047857", + "type": "color" + }, + "800": { + "value": "#065F46", + "type": "color" + }, + "900": { + "value": "#064E3B", + "type": "color" + } + }, + "teal": { + "0": { + "value": "#F0FDFA", + "type": "color" + }, + "100": { + "value": "#CCFBF1", + "type": "color" + }, + "200": { + "value": "#99F6E4", + "type": "color" + }, + "300": { + "value": "#5EEAD4", + "type": "color" + }, + "400": { + "value": "#2DD4BF", + "type": "color" + }, + "500": { + "value": "#14B8A6", + "type": "color" + }, + "600": { + "value": "#0D9488", + "type": "color" + }, + "700": { + "value": "#0F766E", + "type": "color" + }, + "800": { + "value": "#115E59", + "type": "color" + }, + "900": { + "value": "#134E4A", + "type": "color" + } + }, + "cyan": { + "0": { + "value": "#ECFEFF", + "type": "color" + }, + "100": { + "value": "#CFFAFE", + "type": "color" + }, + "200": { + "value": "#A5F3FC", + "type": "color" + }, + "300": { + "value": "#67E8F9", + "type": "color" + }, + "400": { + "value": "#22D3EE", + "type": "color" + }, + "500": { + "value": "#06BBD4", + "type": "color" + }, + "600": { + "value": "#0891B2", + "type": "color" + }, + "700": { + "value": "#0E7490", + "type": "color" + }, + "800": { + "value": "#155E75", + "type": "color" + }, + "900": { + "value": "#164E63", + "type": "color" + } + }, + "sky": { + "0": { + "value": "#F0F9FF", + "type": "color" + }, + "100": { + "value": "#E0F2FE", + "type": "color" + }, + "200": { + "value": "#BAE6FD", + "type": "color" + }, + "300": { + "value": "#7DD3FC", + "type": "color" + }, + "400": { + "value": "#38BDF8", + "type": "color" + }, + "500": { + "value": "#0EA5E9", + "type": "color" + }, + "600": { + "value": "#0284C7", + "type": "color" + }, + "700": { + "value": "#0369A1", + "type": "color" + }, + "800": { + "value": "#075985", + "type": "color" + }, + "900": { + "value": "#0C4A6E", + "type": "color" + } + }, + "blue": { + "0": { + "value": "#EFF6FF", + "type": "color" + }, + "100": { + "value": "#DBEAFE", + "type": "color" + }, + "200": { + "value": "#BFDBFE", + "type": "color" + }, + "300": { + "value": "#93C5FD", + "type": "color" + }, + "400": { + "value": "#60A5FA", + "type": "color" + }, + "500": { + "value": "#3B82F6", + "type": "color" + }, + "600": { + "value": "#2563EB", + "type": "color" + }, + "700": { + "value": "#1D4ED8", + "type": "color" + }, + "800": { + "value": "#1E40A4", + "type": "color" + }, + "900": { + "value": "#1E3A8A", + "type": "color" + } + }, + "indigo": { + "0": { + "value": "#EEF2FF", + "type": "color" + }, + "100": { + "value": "#E0E7FF", + "type": "color" + }, + "200": { + "value": "#C7D2FE", + "type": "color" + }, + "300": { + "value": "#A5B4FC", + "type": "color" + }, + "400": { + "value": "#818CF8", + "type": "color" + }, + "500": { + "value": "#6366F1", + "type": "color" + }, + "600": { + "value": "#4F46E5", + "type": "color" + }, + "700": { + "value": "#4338CA", + "type": "color" + }, + "800": { + "value": "#3730A3", + "type": "color" + }, + "900": { + "value": "#312E81", + "type": "color" + } + }, + "violet": { + "0": { + "value": "#F5F3FF", + "type": "color" + }, + "100": { + "value": "#EDE9FE", + "type": "color" + }, + "200": { + "value": "#DDD6FE", + "type": "color" + }, + "300": { + "value": "#C4B5FD", + "type": "color" + }, + "400": { + "value": "#A78BFA", + "type": "color" + }, + "500": { + "value": "#8B5CF6", + "type": "color" + }, + "600": { + "value": "#7C3AED", + "type": "color" + }, + "700": { + "value": "#6D28D9", + "type": "color" + }, + "800": { + "value": "#5B21B6", + "type": "color" + }, + "900": { + "value": "#4C1D95", + "type": "color" + } + }, + "purple": { + "0": { + "value": "#FAF5FF", + "type": "color" + }, + "100": { + "value": "#F3E8FF", + "type": "color" + }, + "200": { + "value": "#E9D5FF", + "type": "color" + }, + "300": { + "value": "#D8B4FE", + "type": "color" + }, + "400": { + "value": "#C084FC", + "type": "color" + }, + "500": { + "value": "#A855F7", + "type": "color" + }, + "600": { + "value": "#9333EA", + "type": "color" + }, + "700": { + "value": "#7E22CE", + "type": "color" + }, + "800": { + "value": "#6B21A8", + "type": "color" + }, + "900": { + "value": "#581C87", + "type": "color" + } + }, + "fuschia": { + "0": { + "value": "#FDF4FF", + "type": "color" + }, + "100": { + "value": "#FAE8FF", + "type": "color" + }, + "200": { + "value": "#F5D0FE", + "type": "color" + }, + "300": { + "value": "#F0ABFC", + "type": "color" + }, + "400": { + "value": "#E879F9", + "type": "color" + }, + "500": { + "value": "#D946E4", + "type": "color" + }, + "600": { + "value": "#C026D3", + "type": "color" + }, + "700": { + "value": "#A21CAF", + "type": "color" + }, + "800": { + "value": "#86198F", + "type": "color" + }, + "900": { + "value": "#701A75", + "type": "color" + } + }, + "pink": { + "0": { + "value": "#FDF2F8", + "type": "color" + }, + "100": { + "value": "#FCE7F3", + "type": "color" + }, + "200": { + "value": "#FBCFE8", + "type": "color" + }, + "300": { + "value": "#F988D4", + "type": "color" + }, + "400": { + "value": "#F472B6", + "type": "color" + }, + "500": { + "value": "#EC4899", + "type": "color" + }, + "600": { + "value": "#DB2777", + "type": "color" + }, + "700": { + "value": "#BE185D", + "type": "color" + }, + "800": { + "value": "#9D174D", + "type": "color" + }, + "900": { + "value": "#831843", + "type": "color" + } + } + }, + "font-weight": { + "normal": { + "100": { + "value": "Thin", + "type": "fontWeights" + }, + "200": { + "value": "Light", + "type": "fontWeights" + }, + "400": { + "value": "Regular", + "type": "fontWeights" + }, + "500": { + "value": "Semibold", + "type": "fontWeights" + }, + "600": { + "value": "Bold", + "type": "fontWeights" + }, + "800": { + "value": "Heavy", + "type": "fontWeights" + } + }, + "normal-bold": { + "100": { + "value": "Thin", + "type": "fontWeights" + }, + "200": { + "value": "Light", + "type": "fontWeights" + }, + "400": { + "value": "Regular", + "type": "fontWeights" + }, + "500": { + "value": "Semibold", + "type": "fontWeights" + }, + "600": { + "value": "Bold", + "type": "fontWeights" + }, + "800": { + "value": "Heavy", + "type": "fontWeights" + } + }, + "italic": { + "100": { + "value": "Thin Italic", + "type": "fontWeights" + }, + "200": { + "value": "Light", + "type": "fontWeights" + }, + "400": { + "value": "Regular", + "type": "fontWeights" + }, + "500": { + "value": "Semibold", + "type": "fontWeights" + }, + "600": { + "value": "Bold", + "type": "fontWeights" + }, + "800": { + "value": "Heavy", + "type": "fontWeights" + } + }, + "italic-bold": { + "100": { + "value": "Thin Italic", + "type": "fontWeights" + }, + "200": { + "value": "Light", + "type": "fontWeights" + }, + "400": { + "value": "Regular", + "type": "fontWeights" + }, + "500": { + "value": "Semibold", + "type": "fontWeights" + }, + "600": { + "value": "Bold", + "type": "fontWeights" + }, + "800": { + "value": "Heavy", + "type": "fontWeights" + } + } + }, + "font-family": { + "zed-mono": { + "value": "Zed Mono", + "type": "fontFamilies" + }, + "zed-sans": { + "value": "Zed Sans", + "type": "fontFamilies" + } + }, + "font-size": { + "3xs": { + "value": "8", + "type": "fontSizes" + }, + "2xs": { + "value": "10", + "type": "fontSizes" + }, + "xs": { + "value": "12", + "type": "fontSizes" + }, + "sm": { + "value": "14", + "type": "fontSizes" + }, + "base": { + "value": "16", + "type": "fontSizes" + }, + "lg": { + "value": "18", + "type": "fontSizes" + }, + "xl": { + "value": "20", + "type": "fontSizes" + } + }, + "leading": { + "xs": { + "value": "16", + "type": "lineHeights" + }, + "sm": { + "value": "20", + "type": "lineHeights" + }, + "base": { + "value": "24", + "type": "lineHeights" + }, + "lg": { + "value": "26", + "type": "lineHeights" + }, + "xl": { + "value": "28", + "type": "lineHeights" + }, + "2xl": { + "value": "30", + "type": "lineHeights" + } + }, + "text-decoration": { + "none": { + "value": "none", + "type": "textDecoration" + } + }, + "ui-text": { + "normal": { + "base": { + "value": { + "fontFamily": "{font-family.zed-sans}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.sm}", + "fontSize": "{font-size.sm}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography", + "bold": { + "value": { + "fontFamily": "$text.family.zed-sans", + "fontWeight": "$text.weight.bold", + "lineHeight": "$text.leading.base", + "fontSize": "$text.size.xs", + "letterSpacing": "$text.tracking.default", + "paragraphSpacing": "$text.paragraphSpacing.0", + "textCase": "$text.case.default", + "decoration": "$text.decoration.none", + "textDecoration": "$text.decoration.none" + }, + "type": "typography" + } + }, + "sm": { + "value": { + "fontFamily": "{font-family.zed-sans}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.xs}", + "fontSize": "{font-size.xs}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography", + "bold": { + "value": { + "fontFamily": "$text.family.zed-sans", + "fontWeight": "$text.weight.bold", + "lineHeight": "$text.leading.base", + "fontSize": "$text.size.xs", + "letterSpacing": "$text.tracking.default", + "paragraphSpacing": "$text.paragraphSpacing.0", + "textCase": "$text.case.default", + "decoration": "$text.decoration.none", + "textDecoration": "$text.decoration.none" + }, + "type": "typography" + } + } + }, + "bold": { + "base": { + "value": { + "fontFamily": "{font-family.zed-sans}", + "fontWeight": "$font-weight.normal.600", + "lineHeight": "{leading.base}", + "fontSize": "{font-size.sm}", + "letterSpacing": "{letter-spacing.sm}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography" + }, + "sm": { + "value": { + "fontFamily": "{font-family.zed-sans}", + "fontWeight": "$font-weight.normal.600", + "lineHeight": "{leading.xs}", + "fontSize": "{font-size.xs}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography" + } + } + }, + "buffer-text": { + "normal": { + "xs": { + "value": { + "fontFamily": "{font-family.zed-mono}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.xs}", + "fontSize": "{font-size.xs}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography" + }, + "sm": { + "value": { + "fontFamily": "{font-family.zed-mono}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.sm}", + "fontSize": "{font-size.sm}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "{text-decoration.none}" + }, + "type": "typography" + }, + "base": { + "value": { + "fontFamily": "{font-family.zed-mono}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.lg}", + "fontSize": "{font-size.base}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "$text.decoration.default" + }, + "type": "typography" + }, + "lg": { + "value": { + "fontFamily": "{font-family.zed-mono}", + "fontWeight": "$font-weight.normal.400", + "lineHeight": "{leading.lg}", + "fontSize": "{font-size.lg}", + "letterSpacing": "{letter-spacing.base}", + "paragraphSpacing": "{paragraph-spacing.default}", + "textCase": "{text-case.default}", + "decoration": "{text-decoration.none}", + "textDecoration": "$text.decoration.default" + }, + "type": "typography" + } + } + }, + "letter-spacing": { + "tight": { + "value": "-0.05", + "type": "letterSpacing" + }, + "base": { + "value": "0%", + "type": "letterSpacing" + }, + "wide": { + "value": "0.05", + "type": "letterSpacing" + } + }, + "paragraph-spacing": { + "default": { + "value": "0", + "type": "paragraphSpacing" + } + }, + "text-case": { + "default": { + "value": "none", + "type": "textCase" + }, + "lowercase": { + "value": "lowercase", + "type": "textCase" + }, + "uppercase": { + "value": "uppercase", + "type": "textCase" + } + }, + "space": { + "s-0": { + "value": "0", + "type": "spacing" + }, + "s-4": { + "value": "{var.base}", + "type": "spacing" + }, + "s-8": { + "value": "{var.base} * 2", + "type": "spacing" + }, + "s-12": { + "value": "{var.base} * 3", + "type": "spacing" + }, + "s-16": { + "value": "{var.base} * 4", + "type": "spacing" + } + }, + "internal": { + "mac-os": { + "red": { + "value": "#FF5E57", + "type": "color" + }, + "yellow": { + "value": "#FFBB2E", + "type": "color" + }, + "green": { + "value": "#38C149", + "type": "color" + } + } + }, + "border-radius": { + "xs": { + "value": "2", + "type": "borderRadius" + }, + "sm": { + "value": "4", + "type": "borderRadius" + }, + "base": { + "value": "6", + "type": "borderRadius" + }, + "lg": { + "value": "8", + "type": "borderRadius" + }, + "xl": { + "value": "10", + "type": "borderRadius" + } + }, + "border-width": { + "base": { + "value": "1", + "type": "borderWidth" + } + }, + "elevation": { + "300": { + "value": { + "x": "0", + "y": "4", + "blur": "12", + "spread": "0", + "color": "rgba({color.neutral.900}, {shadow.base})", + "type": "dropShadow" + }, + "type": "boxShadow" + } + }, + "var": { + "base": { + "value": "4", + "type": "other" + } + } + }, + "dark": { + "text-color": { + "primary": { + "value": "{color.neutral.150}", + "type": "color" + }, + "secondary": { + "value": "{color.neutral.350}", + "type": "color" + }, + "muted": { + "value": "{color.neutral.550}", + "type": "color" + }, + "minimal": { + "value": "{color.neutral.750}", + "type": "color" + }, + "active": { + "value": "{color.neutral.0}", + "type": "color" + }, + "disabled": { + "value": "{color.neutral.650}", + "type": "color" + }, + "positive": { + "value": "{color.green.600}", + "type": "color" + }, + "negative": { + "value": "{color.red.400}", + "type": "color" + }, + "warning": { + "value": "{color.amber.300}", + "type": "color" + }, + "info": { + "value": "{color.blue.500}", + "type": "color" + } + }, + "icon-color": { + "primary": { + "value": "{text.secondary}", + "type": "color" + }, + "secondary": { + "value": "{text.muted}", + "type": "color" + }, + "active": { + "value": "{text.active}", + "type": "color" + }, + "disabled": { + "value": "{text.disabled}", + "type": "color" + }, + "positive": { + "value": "{color.green.600}", + "type": "color" + }, + "negative": { + "value": "{color.red.400}", + "type": "color" + }, + "warning": { + "value": "{color.amber.300}", + "type": "color" + }, + "info": { + "value": "{color.blue.500}", + "type": "color" + } + }, + "icon-size": { + "default": { + "value": "16", + "type": "size" + } + }, + "background-color": { + "100": { + "value": "{color.neutral.750}", + "type": "color", + "description": "The app background. Used for title-bar, other daylight." + }, + "300": { + "value": "{color.neutral.800}", + "type": "color", + "description": "The primary surface layer. Used for tabs, panels, pop-overs, etc." + }, + "500": { + "value": "{color.neutral.900}", + "type": "color", + "description": "Used for the buffer background and active buffer tabs." + }, + "active": { + "value": "rgba({icon.active}}, 0.1)", + "type": "color" + }, + "focused": { + "value": "// wip", + "type": "color" + }, + "disabled": { + "value": "// wip", + "type": "color" + }, + "positive": { + "value": "{color.green.600}", + "type": "color" + }, + "negative": { + "value": "{color.red.400}", + "type": "color" + }, + "warning": { + "value": "{color.amber.300}", + "type": "color" + }, + "info": { + "value": "{color.blue.500}", + "type": "color" + } + }, + "border-color": { + "default": { + "value": "{color.neutral.850}", + "type": "color" + }, + "secondary": { + "value": "{color.neutral.700}", + "type": "color" + }, + "minimal": { + "value": "{color.neutral.750}", + "type": "color" + }, + "active": { + "value": "{color.neutral.500}", + "type": "color" + }, + "focused": { + "value": "{color.neutral.100}", + "type": "color" + } + }, + "editor": { + "background-color": { + "value": "{surface.500}", + "type": "color" + }, + "indent-guide": { + "value": "{icon.disabled}", + "type": "color" + }, + "indent-guide-active": { + "value": "{icon.secondary}", + "type": "color" + }, + "highlight": { + "active-line": { + "value": "rgba({color.neutral.0}, 0.08)", + "type": "color" + }, + "selection": { + "value": "{player.selection.one}", + "type": "color" + }, + "folded-line": { + "value": "rgba({surface.500}, 0.03)", + "type": "color" + }, + "occurrence": { + "value": "rgba({text.active}, 0.15)", + "type": "color" + }, + "matching-bracket": { + "value": "rgba({color.indigo.500}, 0.8)", + "type": "color" + }, + "match": { + "value": "rgba({color.blue.500},0.5)", + "type": "color" + }, + "active-match": { + "value": "rgba({color.blue.500},0.8)", + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "{text.muted}", + "type": "color" + }, + "active": { + "value": "{text.active}", + "type": "color" + } + }, + "syntax": { + "primary": { + "value": "{text.primary}", + "type": "color" + }, + "comment": { + "value": "{color.lime.200}", + "type": "color" + }, + "punctuation": { + "value": "{text.secondary}", + "type": "color" + }, + "constant": { + "value": "{syntax.primary}", + "type": "color" + }, + "keyword": { + "value": "{color.sky.400}", + "type": "color" + }, + "function": { + "value": "{color.yellow.200}", + "type": "color" + }, + "type": { + "value": "{color.teal.300}", + "type": "color" + }, + "variant": { + "value": "{syntax.type}", + "type": "color" + }, + "property": { + "value": "{color.sky.300}", + "type": "color" + }, + "enum": { + "value": "{syntax.operator}", + "type": "color" + }, + "operator": { + "value": "{syntax.keyword}", + "type": "color" + }, + "string": { + "value": "{color.orange.300}", + "type": "color" + }, + "number": { + "value": "{syntax.primary}", + "type": "color" + }, + "boolean": { + "value": "{syntax.number}", + "type": "color" + }, + "predictive": { + "value": "{text.muted}", + "type": "color" + } + } + }, + "player": { + "color": { + "1": { + "value": "{color.blue.600}", + "type": "color" + }, + "2": { + "value": "{color.indigo.500}", + "type": "color" + }, + "3": { + "value": "{color.green.500}", + "type": "color" + }, + "4": { + "value": "{color.orange.500}", + "type": "color" + }, + "5": { + "value": "{color.purple.500}", + "type": "color" + }, + "6": { + "value": "{color.teal.400}", + "type": "color" + }, + "7": { + "value": "{color.pink.400}", + "type": "color" + }, + "8": { + "value": "{color.yellow.400}", + "type": "color" + } + }, + "selection": { + "1": { + "value": "rgba({color.blue.600},0.1)", + "type": "color" + }, + "2": { + "value": "rgba({color.indigo.500}, 0.1)", + "type": "color" + }, + "3": { + "value": "rgba({color.green.500}, 0.1)", + "type": "color" + }, + "4": { + "value": "rgba({color.orange.500}, 0.15)", + "type": "color" + }, + "5": { + "value": "rgba({color.purple.500}, 0.1)", + "type": "color" + }, + "6": { + "value": "rgba({color.teal.400}, 0.1)", + "type": "color" + }, + "7": { + "value": "rgba({color.pink.400}, 0.1)", + "type": "color" + }, + "8": { + "value": "rgba({color.yellow.400}, 0.15)", + "type": "color" + } + } + }, + "shadow": { + "base": { + "value": "0.36", + "type": "opacity" + } + } + } +} \ No newline at end of file diff --git a/styles/dark.ts b/styles/dark.ts index efd2d3b8a49b1b43c53b8ee782d13615c0f3e0d2..bfcac3db816697fdb537860e7ed8a4e981ccd860 100644 --- a/styles/dark.ts +++ b/styles/dark.ts @@ -2,455 +2,457 @@ import core from "./core"; import Theme from "./theme"; const backgroundColor = { - 100: { - base: { - value: core.color.neutral[999].value, + 100: { + base: { + value: core.color.neutral[999].value, + }, + hovered: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + focused: { + value: core.color.neutral[999].value, + }, + }, + 300: { + base: { + value: core.color.neutral[999].value, + }, + hovered: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + focused: { + value: core.color.neutral[999].value, + }, + }, + 500: { + base: { + value: core.color.neutral[999].value, + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + ok: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + error: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + warning: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, + }, + info: { + base: { + value: "#000000", + }, + hovered: { + value: "#000000", + }, + active: { + value: "#000000", + }, + focused: { + value: "#000000", + }, }, - hovered: { - value: core.color.neutral[999].value, - }, - active: { - value: core.color.neutral[999].value, - }, - focused: { - value: core.color.neutral[999].value, - }, - }, - 300: { - base: { - value: core.color.neutral[999].value, +}; + +const borderColor = { + primary: { + value: "#000000", }, - hovered: { - value: core.color.neutral[999].value, + secondary: { + value: "#000000", }, - active: { - value: core.color.neutral[999].value, + muted: { + value: "#000000", }, focused: { - value: core.color.neutral[999].value, - }, - }, - 500: { - base: { - value: core.color.neutral[999].value, - }, - hovered: { - value: "#000000", + value: "#000000", }, active: { - value: "#000000", - }, - focused: { - value: "#000000", + value: "#000000", }, - }, - ok: { - base: { - value: "#000000", + ok: { + value: "#000000", }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", + error: { + value: "#000000", }, - }, - error: { - base: { - value: "#000000", + warning: { + value: "#000000", }, - hovered: { - value: "#000000", + info: { + value: "#000000", }, - active: { - value: "#000000", +}; + +const textColor = { + primary: { + value: core.color.neutral[150].value, }, - focused: { - value: "#000000", + secondary: { + value: core.color.neutral[350].value, }, - }, - warning: { - base: { - value: "#000000", + muted: { + value: core.color.neutral[550].value, }, - hovered: { - value: "#000000", + placeholder: { + value: core.color.neutral[750].value, }, active: { - value: "#000000", + value: core.color.neutral[0].value, }, - focused: { - value: "#000000", + feature: { + //TODO: (design) define feature and it's correct value + value: core.color.sky[500].value, }, - }, - info: { - base: { - value: "#000000", + ok: { + value: core.color.green[600].value, }, - hovered: { - value: "#000000", + error: { + value: core.color.red[400].value, }, - active: { - value: "#000000", + warning: { + value: core.color.amber[300].value, }, - focused: { - value: "#000000", + info: { + value: core.color.blue[500].value, }, - }, -}; - -const borderColor = { - primary: { - value: "#000000", - }, - secondary: { - value: "#000000", - }, - muted: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - active: { - value: "#000000", - }, - ok: { - value: "#000000", - }, - error: { - value: "#000000", - }, - warning: { - value: "#000000", - }, - info: { - value: "#000000", - }, -}; - -const textColor = { - primary: { - value: core.color.neutral[150].value, - }, - secondary: { - value: core.color.neutral[350].value, - }, - muted: { - value: core.color.neutral[550].value, - }, - placeholder: { - value: core.color.neutral[750].value, - }, - active: { - value: core.color.neutral[0].value, - }, - feature: { - //TODO: (design) define feature and it's correct value - value: core.color.sky[500].value, - }, - ok: { - value: core.color.green[600].value, - }, - error: { - value: core.color.red[400].value, - }, - warning: { - value: core.color.amber[300].value, - }, - info: { - value: core.color.blue[500].value, - }, }; const iconColor = { - primary: { - value: core.color.neutral[300].value, - }, - secondary: { - value: core.color.neutral[500].value, - }, - muted: { - value: core.color.neutral[600].value, - }, - placeholder: { - value: core.color.neutral[700].value, - }, - active: { - value: core.color.neutral[50].value, - }, - feature: { - //TODO: (design) define feature and it's correct value - value: core.color.sky[500].value, - }, - ok: { - value: core.color.green[600].value, - }, - error: { - value: core.color.red[400].value, - }, - warning: { - value: core.color.amber[300].value, - }, - info: { - value: core.color.blue[500].value, - }, -}; - -const editor = { - background: { - value: backgroundColor[500].base.value, - }, - indent_guide: { - value: core.color.neutral[999].value, - }, - indent_guide_active: { - value: core.color.neutral[999].value, - }, - line: { - active: { - value: core.color.neutral[999].value, - }, - highlighted: { - value: core.color.neutral[999].value, - }, - inserted: { - value: core.color.neutral[999].value, - }, - deleted: { - value: core.color.neutral[999].value, - }, - modified: { - value: core.color.neutral[999].value, + primary: { + value: core.color.neutral[300].value, }, - }, - highlight: { - selection: { - value: core.color.neutral[999].value, + secondary: { + value: core.color.neutral[500].value, }, - occurrence: { - value: core.color.neutral[999].value, + muted: { + value: core.color.neutral[600].value, }, - activeOccurrence: { - value: core.color.neutral[999].value, + placeholder: { + value: core.color.neutral[700].value, }, - matchingBracket: { - value: core.color.neutral[999].value, + active: { + value: core.color.neutral[50].value, }, - match: { - value: core.color.neutral[999].value, + feature: { + //TODO: (design) define feature and it's correct value + value: core.color.sky[500].value, }, - activeMatch: { - value: core.color.neutral[999].value, + ok: { + value: core.color.green[600].value, }, - related: { - value: core.color.neutral[999].value, + error: { + value: core.color.red[400].value, }, - }, - gutter: { - primary: { - value: core.color.neutral[999].value, + warning: { + value: core.color.amber[300].value, }, - active: { - value: core.color.neutral[999].value, + info: { + value: core.color.blue[500].value, }, - }, }; -const syntax = { - primary: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - comment: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - punctuation: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - constant: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - keyword: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - function: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - type: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - variant: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - property: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - enum: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - operator: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - string: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - number: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - boolean: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, - predictive: { - color: { value: "000000" }, - weight: { value: "normal" }, - }, +const editor = { + background: { + value: backgroundColor[500].base.value, + }, + indent_guide: { + value: core.color.neutral[999].value, + }, + indent_guide_active: { + value: core.color.neutral[999].value, + }, + line: { + active: { + value: core.color.neutral[999].value, + }, + highlighted: { + value: core.color.neutral[999].value, + }, + inserted: { + value: core.color.neutral[999].value, + }, + deleted: { + value: core.color.neutral[999].value, + }, + modified: { + value: core.color.neutral[999].value, + }, + }, + highlight: { + selection: { + value: core.color.neutral[999].value, + }, + occurrence: { + value: core.color.neutral[999].value, + }, + activeOccurrence: { + value: core.color.neutral[999].value, + }, + matchingBracket: { + value: core.color.neutral[999].value, + }, + match: { + value: core.color.neutral[999].value, + }, + activeMatch: { + value: core.color.neutral[999].value, + }, + related: { + value: core.color.neutral[999].value, + }, + }, + gutter: { + primary: { + value: core.color.neutral[999].value, + }, + active: { + value: core.color.neutral[999].value, + }, + }, }; -const player = { - 1: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, - }, - 2: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, - }, - 3: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, - }, - 4: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, - }, - 5: { - baseColor: { - value: core.color.neutral[999].value, +const syntax = { + primary: { + color: { + value: core.color.neutral[150] + }, + weight: { value: "normal" }, }, - cursorColor: { - value: core.color.neutral[999].value, + comment: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - selectionColor: { - value: core.color.neutral[999].value, + punctuation: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - borderColor: { - value: core.color.neutral[999].value, + constant: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - }, - 6: { - baseColor: { - value: core.color.neutral[999].value, + keyword: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - cursorColor: { - value: core.color.neutral[999].value, + function: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - selectionColor: { - value: core.color.neutral[999].value, + type: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - borderColor: { - value: core.color.neutral[999].value, + variant: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - }, - 7: { - baseColor: { - value: core.color.neutral[999].value, + property: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - cursorColor: { - value: core.color.neutral[999].value, + enum: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - selectionColor: { - value: core.color.neutral[999].value, + operator: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - borderColor: { - value: core.color.neutral[999].value, + string: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - }, - 8: { - baseColor: { - value: core.color.neutral[999].value, + number: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - cursorColor: { - value: core.color.neutral[999].value, + boolean: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - selectionColor: { - value: core.color.neutral[999].value, + predictive: { + color: { value: "000000" }, + weight: { value: "normal" }, }, - borderColor: { - value: core.color.neutral[999].value, +}; + +const player = { + 1: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 2: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 3: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 4: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 5: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 6: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 7: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, + }, + 8: { + baseColor: { + value: core.color.neutral[999].value, + }, + cursorColor: { + value: core.color.neutral[999].value, + }, + selectionColor: { + value: core.color.neutral[999].value, + }, + borderColor: { + value: core.color.neutral[999].value, + }, }, - }, }; const shadowAlpha = { - value: 0.32, + value: 0.32, }; export default function dark(): Theme { - return { - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, - }; + return { + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, + }; } From f11e0aeda936b60ff42578e82a4a6cca43eb5813 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 19:05:21 -0700 Subject: [PATCH 51/68] wip --- styles/core.ts | 102 +++++------ styles/dark.ts | 462 +++++++++++++----------------------------------- styles/theme.ts | 358 ++++++++++++++----------------------- 3 files changed, 307 insertions(+), 615 deletions(-) diff --git a/styles/core.ts b/styles/core.ts index e9e81982e456c0ffe151b83ac36767d62140c6ba..49e376b4ebf81968b2681179be46b3c5b27055b6 100644 --- a/styles/core.ts +++ b/styles/core.ts @@ -1,58 +1,58 @@ import { colorRamp } from "./lib"; export default { - fontFamily: { - sans: "Zed Sans", - mono: "Zed Mono", - }, - fontSize: { - "3xs": { - value: "8", - type: "fontSizes", + fontFamily: { + sans: "Zed Sans", + mono: "Zed Mono", }, - "2xs": { - value: "10", - type: "fontSizes", + fontSize: { + "3xs": { + value: "8", + type: "fontSizes", + }, + "2xs": { + value: "10", + type: "fontSizes", + }, + xs: { + value: "12", + type: "fontSizes", + }, + sm: { + value: "14", + type: "fontSizes", + }, + md: { + value: "16", + type: "fontSizes", + }, + lg: { + value: "18", + type: "fontSizes", + }, + xl: { + value: "20", + type: "fontSizes", + }, }, - xs: { - value: "12", - type: "fontSizes", + color: { + neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), + rose: colorRamp("#F43F5EFF"), + red: colorRamp("#EF4444FF"), + orange: colorRamp("#F97316FF"), + amber: colorRamp("#F59E0BFF"), + yellow: colorRamp("#EAB308FF"), + lime: colorRamp("#84CC16FF"), + green: colorRamp("#22C55EFF"), + emerald: colorRamp("#10B981FF"), + teal: colorRamp("#14B8A6FF"), + cyan: colorRamp("#06BBD4FF"), + sky: colorRamp("#0EA5E9FF"), + blue: colorRamp("#3B82F6FF"), + indigo: colorRamp("#6366F1FF"), + violet: colorRamp("#8B5CF6FF"), + purple: colorRamp("#A855F7FF"), + fuschia: colorRamp("#D946E4FF"), + pink: colorRamp("#EC4899FF"), }, - sm: { - value: "14", - type: "fontSizes", - }, - md: { - value: "16", - type: "fontSizes", - }, - lg: { - value: "18", - type: "fontSizes", - }, - xl: { - value: "20", - type: "fontSizes", - }, - }, - color: { - neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), - rose: colorRamp("#F43F5EFF"), - red: colorRamp("#EF4444FF"), - orange: colorRamp("#F97316FF"), - amber: colorRamp("#F59E0BFF"), - yellow: colorRamp("#EAB308FF"), - lime: colorRamp("#84CC16FF"), - green: colorRamp("#22C55EFF"), - emerald: colorRamp("#10B981FF"), - teal: colorRamp("#14B8A6FF"), - cyan: colorRamp("#06BBD4FF"), - sky: colorRamp("#0EA5E9FF"), - blue: colorRamp("#3B82F6FF"), - indigo: colorRamp("#6366F1FF"), - violet: colorRamp("#8B5CF6FF"), - purple: colorRamp("#A855F7FF"), - fuschia: colorRamp("#D946E4FF"), - pink: colorRamp("#EC4899FF"), - }, }; diff --git a/styles/dark.ts b/styles/dark.ts index bfcac3db816697fdb537860e7ed8a4e981ccd860..5b60bd0316a53fc24a830e23d428088675ac45de 100644 --- a/styles/dark.ts +++ b/styles/dark.ts @@ -1,442 +1,230 @@ import core from "./core"; import Theme from "./theme"; +const { color } = core; + const backgroundColor = { 100: { - base: { - value: core.color.neutral[999].value, - }, - hovered: { - value: core.color.neutral[999].value, - }, - active: { - value: core.color.neutral[999].value, - }, - focused: { - value: core.color.neutral[999].value, - }, + base: color.neutral[750], + hovered: color.neutral[750], + active: color.neutral[750], + focused: color.neutral[750], }, 300: { - base: { - value: core.color.neutral[999].value, - }, - hovered: { - value: core.color.neutral[999].value, - }, - active: { - value: core.color.neutral[999].value, - }, - focused: { - value: core.color.neutral[999].value, - }, + base: color.neutral[800], + hovered: color.neutral[800], + active: color.neutral[800], + focused: color.neutral[800], }, 500: { - base: { - value: core.color.neutral[999].value, - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, + base: color.neutral[900], + hovered: color.neutral[900], + active: color.neutral[900], + focused: color.neutral[900], }, ok: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, + base: color.green[600], + hovered: color.green[600], + active: color.green[600], + focused: color.green[600], }, error: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, + base: color.red[400], + hovered: color.red[400], + active: color.red[400], + focused: color.red[400], }, warning: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, + base: color.amber[300], + hovered: color.amber[300], + active: color.amber[300], + focused: color.amber[300], }, info: { - base: { - value: "#000000", - }, - hovered: { - value: "#000000", - }, - active: { - value: "#000000", - }, - focused: { - value: "#000000", - }, + base: color.blue[500], + hovered: color.blue[500], + active: color.blue[500], + focused: color.blue[500], }, }; const borderColor = { - primary: { - value: "#000000", - }, - secondary: { - value: "#000000", - }, - muted: { - value: "#000000", - }, - focused: { - value: "#000000", - }, - active: { - value: "#000000", - }, - ok: { - value: "#000000", - }, - error: { - value: "#000000", - }, - warning: { - value: "#000000", - }, - info: { - value: "#000000", - }, + primary: color.neutral[850], + secondary: color.neutral[700], + muted: color.neutral[750], + focused: color.neutral[100], + active: color.neutral[500], + ok: color.neutral[999], + error: color.neutral[999], + warning: color.neutral[999], + info: color.neutral[999], }; const textColor = { - primary: { - value: core.color.neutral[150].value, - }, - secondary: { - value: core.color.neutral[350].value, - }, - muted: { - value: core.color.neutral[550].value, - }, - placeholder: { - value: core.color.neutral[750].value, - }, - active: { - value: core.color.neutral[0].value, - }, - feature: { - //TODO: (design) define feature and it's correct value - value: core.color.sky[500].value, - }, - ok: { - value: core.color.green[600].value, - }, - error: { - value: core.color.red[400].value, - }, - warning: { - value: core.color.amber[300].value, - }, - info: { - value: core.color.blue[500].value, - }, + primary: color.neutral[150], + secondary: color.neutral[350], + muted: color.neutral[550], + placeholder: color.neutral[750], + active: color.neutral[0], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const iconColor = { - primary: { - value: core.color.neutral[300].value, - }, - secondary: { - value: core.color.neutral[500].value, - }, - muted: { - value: core.color.neutral[600].value, - }, - placeholder: { - value: core.color.neutral[700].value, - }, - active: { - value: core.color.neutral[50].value, - }, - feature: { - //TODO: (design) define feature and it's correct value - value: core.color.sky[500].value, - }, - ok: { - value: core.color.green[600].value, - }, - error: { - value: core.color.red[400].value, - }, - warning: { - value: core.color.amber[300].value, - }, - info: { - value: core.color.blue[500].value, - }, + primary: color.neutral[300], + secondary: color.neutral[500], + muted: color.neutral[600], + placeholder: color.neutral[700], + active: color.neutral[50], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const editor = { - background: { - value: backgroundColor[500].base.value, - }, - indent_guide: { - value: core.color.neutral[999].value, - }, - indent_guide_active: { - value: core.color.neutral[999].value, - }, + background: backgroundColor[500].base, + indent_guide: color.neutral[999], + indent_guide_active: color.neutral[999], line: { - active: { - value: core.color.neutral[999].value, - }, - highlighted: { - value: core.color.neutral[999].value, - }, - inserted: { - value: core.color.neutral[999].value, - }, - deleted: { - value: core.color.neutral[999].value, - }, - modified: { - value: core.color.neutral[999].value, - }, + active: color.neutral[999], + highlighted: color.neutral[999], + inserted: color.neutral[999], + deleted: color.neutral[999], + modified: color.neutral[999], }, highlight: { - selection: { - value: core.color.neutral[999].value, - }, - occurrence: { - value: core.color.neutral[999].value, - }, - activeOccurrence: { - value: core.color.neutral[999].value, - }, - matchingBracket: { - value: core.color.neutral[999].value, - }, - match: { - value: core.color.neutral[999].value, - }, - activeMatch: { - value: core.color.neutral[999].value, - }, - related: { - value: core.color.neutral[999].value, - }, + selection: color.neutral[999], + occurrence: color.neutral[999], + activeOccurrence: color.neutral[999], + matchingBracket: color.neutral[999], + match: color.neutral[999], + activeMatch: color.neutral[999], + related: color.neutral[999], }, gutter: { - primary: { - value: core.color.neutral[999].value, - }, - active: { - value: core.color.neutral[999].value, - }, + primary: color.neutral[999], + active: color.neutral[999], }, }; const syntax = { primary: { - color: { - value: core.color.neutral[150] - }, + color: textColor.primary, weight: { value: "normal" }, }, comment: { - color: { value: "000000" }, + color: color.lime[200], weight: { value: "normal" }, }, punctuation: { - color: { value: "000000" }, + color: textColor.primary, weight: { value: "normal" }, }, constant: { - color: { value: "000000" }, + color: color.neutral[150], weight: { value: "normal" }, }, keyword: { - color: { value: "000000" }, + color: color.sky[400], weight: { value: "normal" }, }, function: { - color: { value: "000000" }, + color: color.yellow[200], weight: { value: "normal" }, }, type: { - color: { value: "000000" }, + color: color.teal[300], weight: { value: "normal" }, }, variant: { - color: { value: "000000" }, + color: color.teal[300], weight: { value: "normal" }, }, property: { - color: { value: "000000" }, + color: color.sky[300], weight: { value: "normal" }, }, enum: { - color: { value: "000000" }, + color: color.sky[400], weight: { value: "normal" }, }, operator: { - color: { value: "000000" }, + color: color.sky[400], weight: { value: "normal" }, }, string: { - color: { value: "000000" }, + color: color.orange[300], weight: { value: "normal" }, }, number: { - color: { value: "000000" }, + color: color.neutral[150], weight: { value: "normal" }, }, boolean: { - color: { value: "000000" }, + color: color.neutral[150], weight: { value: "normal" }, }, predictive: { - color: { value: "000000" }, + color: textColor.muted, weight: { value: "normal" }, }, }; const player = { 1: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.blue[600], + cursorColor: color.blue[600], + selectionColor: color.blue[600], + borderColor: color.blue[600], }, 2: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.indigo[500], + cursorColor: color.indigo[500], + selectionColor: color.indigo[500], + borderColor: color.indigo[500], }, 3: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.green[500], + cursorColor: color.green[500], + selectionColor: color.green[500], + borderColor: color.green[500], }, 4: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.orange[500], + cursorColor: color.orange[500], + selectionColor: color.orange[500], + borderColor: color.orange[500], }, 5: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.purple[500], + cursorColor: color.purple[500], + selectionColor: color.purple[500], + borderColor: color.purple[500], }, 6: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.teal[400], + cursorColor: color.teal[400], + selectionColor: color.teal[400], + borderColor: color.teal[400], }, 7: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.pink[400], + cursorColor: color.pink[400], + selectionColor: color.pink[400], + borderColor: color.pink[400], }, 8: { - baseColor: { - value: core.color.neutral[999].value, - }, - cursorColor: { - value: core.color.neutral[999].value, - }, - selectionColor: { - value: core.color.neutral[999].value, - }, - borderColor: { - value: core.color.neutral[999].value, - }, + baseColor: color.yellow[400], + cursorColor: color.yellow[400], + selectionColor: color.yellow[400], + borderColor: color.yellow[400], }, }; diff --git a/styles/theme.ts b/styles/theme.ts index 9d297d552d38b21154a77b2eed22d49a1ce2a247..9d70ea0227053f81e48d2e3359379db635bed7c8 100644 --- a/styles/theme.ts +++ b/styles/theme.ts @@ -1,242 +1,146 @@ +export interface NumberToken { + value: number, + type: "number" +} + export type Color = string; +export interface ColorToken { + value: Color; + type: "color"; + step?: number +} export type Weight = - | "thin" - | "extra_light" - | "light" - | "normal" - | "medium" - | "semibold" - | "bold" - | "extra_bold" - | "black"; + | "thin" + | "extra_light" + | "light" + | "normal" + | "medium" + | "semibold" + | "bold" + | "extra_bold" + | "black"; +export interface WeightToken { + value: Weight, + type: "fontWeight" +} -interface SyntaxHighlightStyle { - color: { value: Color }; - weight: { value: Weight }; +export interface SyntaxHighlightStyle { + color: ColorToken; + weight: WeightToken; } -interface Player { - baseColor: { - value: Color; - }; - cursorColor: { - value: Color; - }; - selectionColor: { - value: Color; - }; - borderColor: { - value: Color; - }; +export interface Player { + baseColor: ColorToken; + cursorColor: ColorToken; + selectionColor: ColorToken; + borderColor: ColorToken; } export interface BackgroundColor { - base: { - value: Color; - }; - hovered: { - value: Color; - }; - active: { - value: Color; - }; - focused: { - value: Color; - }; + base: ColorToken; + hovered: ColorToken; + active: ColorToken; + focused: ColorToken; } export default interface Theme { - backgroundColor: { - 100: BackgroundColor; - 300: BackgroundColor; - 500: BackgroundColor; - ok: BackgroundColor; - error: BackgroundColor; - warning: BackgroundColor; - info: BackgroundColor; - }; - borderColor: { - primary: { - value: Color; - }; - secondary: { - value: Color; - }; - muted: { - value: Color; - }; - focused: { - value: Color; - }; - active: { - value: Color; - }; - ok: { - value: Color; - }; - error: { - value: Color; - }; - warning: { - value: Color; - }; - info: { - value: Color; - }; - }; - textColor: { - primary: { - value: Color; - }; - secondary: { - value: Color; - }; - muted: { - value: Color; + backgroundColor: { + 100: BackgroundColor; + 300: BackgroundColor; + 500: BackgroundColor; + ok: BackgroundColor; + error: BackgroundColor; + warning: BackgroundColor; + info: BackgroundColor; + }; + borderColor: { + primary: ColorToken; + secondary: ColorToken; + muted: ColorToken; + focused: ColorToken; + active: ColorToken; + ok: ColorToken; + error: ColorToken; + warning: ColorToken; + info: ColorToken; + }; + textColor: { + primary: ColorToken; + secondary: ColorToken; + muted: ColorToken; + placeholder: ColorToken; + active: ColorToken; + feature: ColorToken; + ok: ColorToken; + error: ColorToken; + warning: ColorToken; + info: ColorToken; + }; + iconColor: { + primary: ColorToken; + secondary: ColorToken; + muted: ColorToken; + placeholder: ColorToken; + active: ColorToken; + feature: ColorToken; + ok: ColorToken; + error: ColorToken; + warning: ColorToken; + info: ColorToken; + }; + editor: { + background: ColorToken; + indent_guide: ColorToken; + indent_guide_active: ColorToken; + line: { + active: ColorToken; + highlighted: ColorToken; + inserted: ColorToken; + deleted: ColorToken; + modified: ColorToken; + }; + highlight: { + selection: ColorToken; + occurrence: ColorToken; + activeOccurrence: ColorToken; + matchingBracket: ColorToken; + match: ColorToken; + activeMatch: ColorToken; + related: ColorToken; + }; + gutter: { + primary: ColorToken; + active: ColorToken; + }; }; - placeholder: { - value: Color; - }; - active: { - value: Color; - }; - feature: { - value: Color; - }; - ok: { - value: Color; - }; - error: { - value: Color; - }; - warning: { - value: Color; - }; - info: { - value: Color; - }; - }; - iconColor: { - primary: { - value: Color; - }; - secondary: { - value: Color; - }; - muted: { - value: Color; - }; - placeholder: { - value: Color; - }; - active: { - value: Color; - }; - feature: { - value: Color; - }; - ok: { - value: Color; - }; - error: { - value: Color; - }; - warning: { - value: Color; - }; - info: { - value: Color; - }; - }; - editor: { - background: { - value: Color; - }; - indent_guide: { - value: Color; - }; - indent_guide_active: { - value: Color; - }; - line: { - active: { - value: Color; - }; - highlighted: { - value: Color; - }; - inserted: { - value: Color; - }; - deleted: { - value: Color; - }; - modified: { - value: Color; - }; - }; - highlight: { - selection: { - value: Color; - }; - occurrence: { - value: Color; - }; - activeOccurrence: { - value: Color; - }; - matchingBracket: { - value: Color; - }; - match: { - value: Color; - }; - activeMatch: { - value: Color; - }; - related: { - value: Color; - }; - }; - gutter: { - primary: { - value: Color; - }; - active: { - value: Color; - }; - }; - }; - syntax: { - primary: SyntaxHighlightStyle; - comment: SyntaxHighlightStyle; - punctuation: SyntaxHighlightStyle; - constant: SyntaxHighlightStyle; - keyword: SyntaxHighlightStyle; - function: SyntaxHighlightStyle; - type: SyntaxHighlightStyle; - variant: SyntaxHighlightStyle; - property: SyntaxHighlightStyle; - enum: SyntaxHighlightStyle; - operator: SyntaxHighlightStyle; - string: SyntaxHighlightStyle; - number: SyntaxHighlightStyle; - boolean: SyntaxHighlightStyle; - predictive: SyntaxHighlightStyle; - }; + syntax: { + primary: SyntaxHighlightStyle; + comment: SyntaxHighlightStyle; + punctuation: SyntaxHighlightStyle; + constant: SyntaxHighlightStyle; + keyword: SyntaxHighlightStyle; + function: SyntaxHighlightStyle; + type: SyntaxHighlightStyle; + variant: SyntaxHighlightStyle; + property: SyntaxHighlightStyle; + enum: SyntaxHighlightStyle; + operator: SyntaxHighlightStyle; + string: SyntaxHighlightStyle; + number: SyntaxHighlightStyle; + boolean: SyntaxHighlightStyle; + predictive: SyntaxHighlightStyle; + }; - player: { - 1: Player; - 2: Player; - 3: Player; - 4: Player; - 5: Player; - 6: Player; - 7: Player; - 8: Player; - }; - shadowAlpha: { - value: number; - }; + player: { + 1: Player; + 2: Player; + 3: Player; + 4: Player; + 5: Player; + 6: Player; + 7: Player; + 8: Player; + }; + shadowAlpha: NumberToken; } From bfeb6abb4bedfbb414841b41a72cd435b11b8379 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Thu, 31 Mar 2022 20:27:25 -0700 Subject: [PATCH 52/68] Finish dark.ts initial port and restructure files to get ready for build script Build script currently fails to type check. Not sure whats going on. Will fix in the morning. Co-authored-by: Nate Butler --- styles/.gitignore | 1 + styles/buildStyleTree.ts | 11 + styles/{ => styleTree}/app.ts | 0 .../{chat-panel.ts => styleTree/chatPanel.ts} | 0 styles/{ => styleTree}/components.ts | 6 +- styles/{ => styleTree}/editor.ts | 0 .../projectPanel.ts} | 4 +- styles/{ => styleTree}/search.ts | 0 .../selectorModal.ts} | 0 styles/{ => styleTree}/workspace.ts | 0 styles/{ => themes}/dark.ts | 197 +++++++------- styles/themes/light.ts | 251 ++++++++++++++++++ styles/{ => themes}/theme.ts | 36 +-- styles/{ => tokens}/core.ts | 2 +- styles/{lib.ts => utils/color.ts} | 0 15 files changed, 388 insertions(+), 120 deletions(-) create mode 100644 styles/.gitignore create mode 100644 styles/buildStyleTree.ts rename styles/{ => styleTree}/app.ts (100%) rename styles/{chat-panel.ts => styleTree/chatPanel.ts} (100%) rename styles/{ => styleTree}/components.ts (92%) rename styles/{ => styleTree}/editor.ts (100%) rename styles/{project-panel.ts => styleTree/projectPanel.ts} (90%) rename styles/{ => styleTree}/search.ts (100%) rename styles/{selector-modal.ts => styleTree/selectorModal.ts} (100%) rename styles/{ => styleTree}/workspace.ts (100%) rename styles/{ => themes}/dark.ts (71%) create mode 100644 styles/themes/light.ts rename styles/{ => themes}/theme.ts (82%) rename styles/{ => tokens}/core.ts (97%) rename styles/{lib.ts => utils/color.ts} (100%) diff --git a/styles/.gitignore b/styles/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c2658d7d1b31848c3b71960543cb0368e56cd4c7 --- /dev/null +++ b/styles/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/styles/buildStyleTree.ts b/styles/buildStyleTree.ts new file mode 100644 index 0000000000000000000000000000000000000000..6fa1c1576d96f312c79b52d15ce2429f3902ff8a --- /dev/null +++ b/styles/buildStyleTree.ts @@ -0,0 +1,11 @@ +import dark from "./themes/dark"; +import light from "./themes/light"; +import app from "./styleTree/app"; + +for (let theme of [dark, light]) { + let styleTree = app(theme); + + let styleTreeJson = JSON.stringify(styleTree); + console.log(styleTreeJson); + // TODO: Write style tree json to zed crate assets folder +} \ No newline at end of file diff --git a/styles/app.ts b/styles/styleTree/app.ts similarity index 100% rename from styles/app.ts rename to styles/styleTree/app.ts diff --git a/styles/chat-panel.ts b/styles/styleTree/chatPanel.ts similarity index 100% rename from styles/chat-panel.ts rename to styles/styleTree/chatPanel.ts diff --git a/styles/components.ts b/styles/styleTree/components.ts similarity index 92% rename from styles/components.ts rename to styles/styleTree/components.ts index 590c1b5eea9f6779dee0c2697a781d36b3edee60..b54956facccc3874998176870498368dbe8b5b56 100644 --- a/styles/components.ts +++ b/styles/styleTree/components.ts @@ -1,7 +1,7 @@ import chroma from "chroma-js"; -import core from "./core"; -import { Color } from "./lib"; -import Theme, { BackgroundColor, Weight } from "./theme"; +import core from "../tokens/core"; +import { Color } from "../utils/color"; +import Theme, { BackgroundColor, Weight } from "../themes/theme"; export type TextColor = keyof Theme["textColor"]; diff --git a/styles/editor.ts b/styles/styleTree/editor.ts similarity index 100% rename from styles/editor.ts rename to styles/styleTree/editor.ts diff --git a/styles/project-panel.ts b/styles/styleTree/projectPanel.ts similarity index 90% rename from styles/project-panel.ts rename to styles/styleTree/projectPanel.ts index 343e11b96b6e8adb3c6bd223a71de3e6d7d05f40..3b5fba8853da3799e69be735447e615341ef8391 100644 --- a/styles/project-panel.ts +++ b/styles/styleTree/projectPanel.ts @@ -1,7 +1,7 @@ import { panel } from "./app"; import { backgroundColor, iconColor, text, TextColor } from "./components"; -import Theme from "./theme"; -import { Color } from "./lib"; +import Theme from "../themes/theme"; +import { Color } from "../utils/color"; export default function projectPanel(theme: Theme) { function entry(theme: Theme, textColor: TextColor, background?: Color) { diff --git a/styles/search.ts b/styles/styleTree/search.ts similarity index 100% rename from styles/search.ts rename to styles/styleTree/search.ts diff --git a/styles/selector-modal.ts b/styles/styleTree/selectorModal.ts similarity index 100% rename from styles/selector-modal.ts rename to styles/styleTree/selectorModal.ts diff --git a/styles/workspace.ts b/styles/styleTree/workspace.ts similarity index 100% rename from styles/workspace.ts rename to styles/styleTree/workspace.ts diff --git a/styles/dark.ts b/styles/themes/dark.ts similarity index 71% rename from styles/dark.ts rename to styles/themes/dark.ts index 5b60bd0316a53fc24a830e23d428088675ac45de..098677a1e91c898e1e57624fa28a39fe9bbafee9 100644 --- a/styles/dark.ts +++ b/styles/themes/dark.ts @@ -1,5 +1,5 @@ -import core from "./core"; -import Theme from "./theme"; +import core from "../tokens/core"; +import Theme, { NumberToken, Syntax } from "./theme"; const { color } = core; @@ -88,159 +88,162 @@ const iconColor = { info: color.blue[500], }; +const player = { + 1: { + baseColor: color.blue[600], + cursorColor: color.blue[600], + selectionColor: color.blue[600], + borderColor: color.blue[600], + }, + 2: { + baseColor: color.indigo[500], + cursorColor: color.indigo[500], + selectionColor: color.indigo[500], + borderColor: color.indigo[500], + }, + 3: { + baseColor: color.green[500], + cursorColor: color.green[500], + selectionColor: color.green[500], + borderColor: color.green[500], + }, + 4: { + baseColor: color.orange[500], + cursorColor: color.orange[500], + selectionColor: color.orange[500], + borderColor: color.orange[500], + }, + 5: { + baseColor: color.purple[500], + cursorColor: color.purple[500], + selectionColor: color.purple[500], + borderColor: color.purple[500], + }, + 6: { + baseColor: color.teal[400], + cursorColor: color.teal[400], + selectionColor: color.teal[400], + borderColor: color.teal[400], + }, + 7: { + baseColor: color.pink[400], + cursorColor: color.pink[400], + selectionColor: color.pink[400], + borderColor: color.pink[400], + }, + 8: { + baseColor: color.yellow[400], + cursorColor: color.yellow[400], + selectionColor: color.yellow[400], + borderColor: color.yellow[400], + }, +}; + +// TODO: Fixup const editor = { background: backgroundColor[500].base, - indent_guide: color.neutral[999], - indent_guide_active: color.neutral[999], + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, line: { - active: color.neutral[999], - highlighted: color.neutral[999], - inserted: color.neutral[999], - deleted: color.neutral[999], - modified: color.neutral[999], + active: color.neutral[0], + highlighted: color.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, }, highlight: { - selection: color.neutral[999], - occurrence: color.neutral[999], - activeOccurrence: color.neutral[999], - matchingBracket: color.neutral[999], - match: color.neutral[999], - activeMatch: color.neutral[999], - related: color.neutral[999], + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: color.neutral[0], + matchingBracket: color.neutral[0], + match: color.neutral[0], + activeMatch: color.neutral[0], + related: color.neutral[0], }, gutter: { - primary: color.neutral[999], - active: color.neutral[999], + primary: color.neutral[0], + active: color.neutral[0], }, }; -const syntax = { +const syntax: Syntax = { primary: { color: textColor.primary, - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, comment: { color: color.lime[200], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, punctuation: { color: textColor.primary, - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, constant: { color: color.neutral[150], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, keyword: { color: color.sky[400], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, function: { color: color.yellow[200], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, type: { color: color.teal[300], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, variant: { color: color.teal[300], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, property: { color: color.sky[300], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, enum: { color: color.sky[400], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, operator: { color: color.sky[400], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, string: { color: color.orange[300], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, number: { color: color.neutral[150], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, boolean: { color: color.neutral[150], - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, predictive: { color: textColor.muted, - weight: { value: "normal" }, + weight: { value: "normal", type: "fontWeight" }, }, }; -const player = { - 1: { - baseColor: color.blue[600], - cursorColor: color.blue[600], - selectionColor: color.blue[600], - borderColor: color.blue[600], - }, - 2: { - baseColor: color.indigo[500], - cursorColor: color.indigo[500], - selectionColor: color.indigo[500], - borderColor: color.indigo[500], - }, - 3: { - baseColor: color.green[500], - cursorColor: color.green[500], - selectionColor: color.green[500], - borderColor: color.green[500], - }, - 4: { - baseColor: color.orange[500], - cursorColor: color.orange[500], - selectionColor: color.orange[500], - borderColor: color.orange[500], - }, - 5: { - baseColor: color.purple[500], - cursorColor: color.purple[500], - selectionColor: color.purple[500], - borderColor: color.purple[500], - }, - 6: { - baseColor: color.teal[400], - cursorColor: color.teal[400], - selectionColor: color.teal[400], - borderColor: color.teal[400], - }, - 7: { - baseColor: color.pink[400], - cursorColor: color.pink[400], - selectionColor: color.pink[400], - borderColor: color.pink[400], - }, - 8: { - baseColor: color.yellow[400], - cursorColor: color.yellow[400], - selectionColor: color.yellow[400], - borderColor: color.yellow[400], - }, +const shadowAlpha: NumberToken = { + value: 0.32, + type: "number" }; -const shadowAlpha = { - value: 0.32, +const theme: Theme = { + name: "dark", + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, }; -export default function dark(): Theme { - return { - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, - }; -} +export default theme; \ No newline at end of file diff --git a/styles/themes/light.ts b/styles/themes/light.ts new file mode 100644 index 0000000000000000000000000000000000000000..20760427f273e93d72c2cf7cee6a8c0f6ae7192d --- /dev/null +++ b/styles/themes/light.ts @@ -0,0 +1,251 @@ +import core from "../tokens/core"; +import Theme, { NumberToken, Syntax } from "./theme"; + +const { color } = core; + +// TODO: Replace with light values + +const backgroundColor = { + 100: { + base: color.neutral[750], + hovered: color.neutral[750], + active: color.neutral[750], + focused: color.neutral[750], + }, + 300: { + base: color.neutral[800], + hovered: color.neutral[800], + active: color.neutral[800], + focused: color.neutral[800], + }, + 500: { + base: color.neutral[900], + hovered: color.neutral[900], + active: color.neutral[900], + focused: color.neutral[900], + }, + ok: { + base: color.green[600], + hovered: color.green[600], + active: color.green[600], + focused: color.green[600], + }, + error: { + base: color.red[400], + hovered: color.red[400], + active: color.red[400], + focused: color.red[400], + }, + warning: { + base: color.amber[300], + hovered: color.amber[300], + active: color.amber[300], + focused: color.amber[300], + }, + info: { + base: color.blue[500], + hovered: color.blue[500], + active: color.blue[500], + focused: color.blue[500], + }, +}; + +const borderColor = { + primary: color.neutral[850], + secondary: color.neutral[700], + muted: color.neutral[750], + focused: color.neutral[100], + active: color.neutral[500], + ok: color.neutral[999], + error: color.neutral[999], + warning: color.neutral[999], + info: color.neutral[999], +}; + +const textColor = { + primary: color.neutral[150], + secondary: color.neutral[350], + muted: color.neutral[550], + placeholder: color.neutral[750], + active: color.neutral[0], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], +}; + +const iconColor = { + primary: color.neutral[300], + secondary: color.neutral[500], + muted: color.neutral[600], + placeholder: color.neutral[700], + active: color.neutral[50], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], +}; + +const player = { + 1: { + baseColor: color.blue[600], + cursorColor: color.blue[600], + selectionColor: color.blue[600], + borderColor: color.blue[600], + }, + 2: { + baseColor: color.indigo[500], + cursorColor: color.indigo[500], + selectionColor: color.indigo[500], + borderColor: color.indigo[500], + }, + 3: { + baseColor: color.green[500], + cursorColor: color.green[500], + selectionColor: color.green[500], + borderColor: color.green[500], + }, + 4: { + baseColor: color.orange[500], + cursorColor: color.orange[500], + selectionColor: color.orange[500], + borderColor: color.orange[500], + }, + 5: { + baseColor: color.purple[500], + cursorColor: color.purple[500], + selectionColor: color.purple[500], + borderColor: color.purple[500], + }, + 6: { + baseColor: color.teal[400], + cursorColor: color.teal[400], + selectionColor: color.teal[400], + borderColor: color.teal[400], + }, + 7: { + baseColor: color.pink[400], + cursorColor: color.pink[400], + selectionColor: color.pink[400], + borderColor: color.pink[400], + }, + 8: { + baseColor: color.yellow[400], + cursorColor: color.yellow[400], + selectionColor: color.yellow[400], + borderColor: color.yellow[400], + }, +}; + +// TODO: Fixup +const editor = { + background: backgroundColor[500].base, + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, + line: { + active: color.neutral[0], + highlighted: color.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, + }, + highlight: { + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: color.neutral[0], + matchingBracket: color.neutral[0], + match: color.neutral[0], + activeMatch: color.neutral[0], + related: color.neutral[0], + }, + gutter: { + primary: color.neutral[0], + active: color.neutral[0], + }, +}; + +const syntax: Syntax = { + primary: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + comment: { + color: color.lime[200], + weight: { value: "normal", type: "fontWeight" }, + }, + punctuation: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + constant: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + keyword: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + function: { + color: color.yellow[200], + weight: { value: "normal", type: "fontWeight" }, + }, + type: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + variant: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + property: { + color: color.sky[300], + weight: { value: "normal", type: "fontWeight" }, + }, + enum: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + operator: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + string: { + color: color.orange[300], + weight: { value: "normal", type: "fontWeight" }, + }, + number: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + boolean: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + predictive: { + color: textColor.muted, + weight: { value: "normal", type: "fontWeight" }, + }, +}; + +const shadowAlpha: NumberToken = { + value: 0.32, + type: "number" +}; + +const theme: Theme = { + name: "light", + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, +}; + +export default theme; diff --git a/styles/theme.ts b/styles/themes/theme.ts similarity index 82% rename from styles/theme.ts rename to styles/themes/theme.ts index 9d70ea0227053f81e48d2e3359379db635bed7c8..e319f510c7daa52c64caefc3d8d2c8c7bfde4221 100644 --- a/styles/theme.ts +++ b/styles/themes/theme.ts @@ -43,6 +43,24 @@ export interface BackgroundColor { focused: ColorToken; } +export interface Syntax { + primary: SyntaxHighlightStyle; + comment: SyntaxHighlightStyle; + punctuation: SyntaxHighlightStyle; + constant: SyntaxHighlightStyle; + keyword: SyntaxHighlightStyle; + function: SyntaxHighlightStyle; + type: SyntaxHighlightStyle; + variant: SyntaxHighlightStyle; + property: SyntaxHighlightStyle; + enum: SyntaxHighlightStyle; + operator: SyntaxHighlightStyle; + string: SyntaxHighlightStyle; + number: SyntaxHighlightStyle; + boolean: SyntaxHighlightStyle; + predictive: SyntaxHighlightStyle; +}; + export default interface Theme { backgroundColor: { 100: BackgroundColor; @@ -114,23 +132,7 @@ export default interface Theme { }; }; - syntax: { - primary: SyntaxHighlightStyle; - comment: SyntaxHighlightStyle; - punctuation: SyntaxHighlightStyle; - constant: SyntaxHighlightStyle; - keyword: SyntaxHighlightStyle; - function: SyntaxHighlightStyle; - type: SyntaxHighlightStyle; - variant: SyntaxHighlightStyle; - property: SyntaxHighlightStyle; - enum: SyntaxHighlightStyle; - operator: SyntaxHighlightStyle; - string: SyntaxHighlightStyle; - number: SyntaxHighlightStyle; - boolean: SyntaxHighlightStyle; - predictive: SyntaxHighlightStyle; - }; + syntax: Syntax, player: { 1: Player; diff --git a/styles/core.ts b/styles/tokens/core.ts similarity index 97% rename from styles/core.ts rename to styles/tokens/core.ts index 49e376b4ebf81968b2681179be46b3c5b27055b6..38bfe82e28129954a2f5602038d575a3cfbb94af 100644 --- a/styles/core.ts +++ b/styles/tokens/core.ts @@ -1,4 +1,4 @@ -import { colorRamp } from "./lib"; +import { colorRamp } from "../utils/color"; export default { fontFamily: { diff --git a/styles/lib.ts b/styles/utils/color.ts similarity index 100% rename from styles/lib.ts rename to styles/utils/color.ts From 43a7cadf5bf2c3c7cad3c3fd9a04e153728ff452 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 23:42:45 -0400 Subject: [PATCH 53/68] Type `name` --- styles/themes/theme.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/styles/themes/theme.ts b/styles/themes/theme.ts index e319f510c7daa52c64caefc3d8d2c8c7bfde4221..a7760459897b0bedec0d87512e669d1d7ae0a3b4 100644 --- a/styles/themes/theme.ts +++ b/styles/themes/theme.ts @@ -62,6 +62,7 @@ export interface Syntax { }; export default interface Theme { + name: string; backgroundColor: { 100: BackgroundColor; 300: BackgroundColor; From 211c473d32c0e09f8855d2d504cb1a356d3e58a1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 31 Mar 2022 23:43:01 -0400 Subject: [PATCH 54/68] Update renamed/moved imports --- styles/styleTree/app.ts | 8 ++++---- styles/styleTree/chatPanel.ts | 4 ++-- styles/styleTree/components.ts | 2 +- styles/styleTree/editor.ts | 2 +- styles/styleTree/search.ts | 2 +- styles/styleTree/selectorModal.ts | 2 +- styles/styleTree/workspace.ts | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/styles/styleTree/app.ts b/styles/styleTree/app.ts index a65442db0737630f77d1de92d921d934ed4a8804..c7edfdc2701f06e6cb1b41beb779ad6bc0aca75b 100644 --- a/styles/styleTree/app.ts +++ b/styles/styleTree/app.ts @@ -1,10 +1,10 @@ -import chatPanel from "./chat-panel"; +import Theme from "../themes/theme"; +import chatPanel from "./chatPanel"; import { backgroundColor, borderColor, text } from "./components"; import editor from "./editor"; -import projectPanel from "./project-panel"; +import projectPanel from "./projectPanel"; import search from "./search"; -import selectorModal from "./selector-modal"; -import Theme from "./theme"; +import selectorModal from "./selectorModal"; import workspace from "./workspace"; export const panel = { diff --git a/styles/styleTree/chatPanel.ts b/styles/styleTree/chatPanel.ts index c6bf0148ea4c5d9345c29d5df94c978588e4fd0d..ea9a8ffe22a83e2b7135bc886273f2da2d7c1502 100644 --- a/styles/styleTree/chatPanel.ts +++ b/styles/styleTree/chatPanel.ts @@ -1,3 +1,4 @@ +import Theme from "../themes/theme"; import { panel } from "./app"; import { backgroundColor, @@ -5,9 +6,8 @@ import { player, shadow, text, - TextColor, + TextColor } from "./components"; -import Theme from "./theme"; export default function chatPanel(theme: Theme) { function channelSelectItem( diff --git a/styles/styleTree/components.ts b/styles/styleTree/components.ts index b54956facccc3874998176870498368dbe8b5b56..8038cdcd3b37494e1217fc4557090cb7bfe01378 100644 --- a/styles/styleTree/components.ts +++ b/styles/styleTree/components.ts @@ -1,7 +1,7 @@ import chroma from "chroma-js"; +import Theme, { BackgroundColor, Weight } from "../themes/theme"; import core from "../tokens/core"; import { Color } from "../utils/color"; -import Theme, { BackgroundColor, Weight } from "../themes/theme"; export type TextColor = keyof Theme["textColor"]; diff --git a/styles/styleTree/editor.ts b/styles/styleTree/editor.ts index a27464eee2182ecfb0633623ff4e773cfb85b35d..5d800881e2750942c2b7d6f1113df203aff97fb3 100644 --- a/styles/styleTree/editor.ts +++ b/styles/styleTree/editor.ts @@ -1,3 +1,4 @@ +import Theme from "../themes/theme"; import { backgroundColor, border, @@ -6,7 +7,6 @@ import { text, TextColor } from "./components"; -import Theme from "./theme"; export default function editor(theme: Theme) { const autocompleteItem = { diff --git a/styles/styleTree/search.ts b/styles/styleTree/search.ts index ced2266ea73480da11f880d4c56b4a65aa83f12c..fd2fd2568156f31a877de40773b9382eb5a8e6ca 100644 --- a/styles/styleTree/search.ts +++ b/styles/styleTree/search.ts @@ -1,5 +1,5 @@ +import Theme from "../themes/theme"; import { backgroundColor, border, player, text } from "./components"; -import Theme from "./theme"; export default function search(theme: Theme) { const optionButton = { diff --git a/styles/styleTree/selectorModal.ts b/styles/styleTree/selectorModal.ts index ddba32683a976153eac6fc0f49f6a5df9a835a1f..fdebe712fa0f1650a3fe4411b4579aa30bb44e2e 100644 --- a/styles/styleTree/selectorModal.ts +++ b/styles/styleTree/selectorModal.ts @@ -1,5 +1,5 @@ +import Theme from "../themes/theme"; import { backgroundColor, border, player, shadow, text } from "./components"; -import Theme from "./theme"; export default function selectorModal(theme: Theme): Object { const item = { diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index 1a50fe9ee1c248de6d48a9521efa9f9cc8f82fbb..e8232442b6f01ec2d0e3486509218f4b4c9e7562 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -1,5 +1,5 @@ +import Theme from "../themes/theme"; import { backgroundColor, border, iconColor, text } from "./components"; -import Theme from "./theme"; export default function workspace(theme: Theme) { const signInPrompt = { From 70a783c8d103461d720c332f78054168486ab99b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 1 Apr 2022 08:25:58 -0600 Subject: [PATCH 55/68] Fix TS compile error --- styles/styleTree/components.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/styleTree/components.ts b/styles/styleTree/components.ts index 8038cdcd3b37494e1217fc4557090cb7bfe01378..55a64cb1ecb4ec8f60878d9e795f671a9a5cfede 100644 --- a/styles/styleTree/components.ts +++ b/styles/styleTree/components.ts @@ -15,7 +15,7 @@ export function text( underline?: boolean; } ) { - const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md"; + const sizeKey = properties?.size || fontFamily === "sans" ? "sm" : "md"; const size = core.fontSize[sizeKey].value; return { From d2a070c345d338a46d968d61a6ee0115629f9698 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 1 Apr 2022 09:45:11 -0600 Subject: [PATCH 56/68] Write theme JSON files from buildThemes script Co-Authored-By: Nate Butler <1714999+iamnbutler@users.noreply.github.com> --- script/build-themes | 7 + styles/buildStyleTree.ts | 11 - styles/buildThemes.ts | 17 ++ styles/package-lock.json | 279 ++++++++++++++++++++- styles/package.json | 7 +- styles/themes/dark.ts | 432 ++++++++++++++++----------------- styles/themes/light.ts | 430 ++++++++++++++++---------------- styles/tsconfig.json | 12 + styles/utils/decamelizeTree.ts | 21 ++ 9 files changed, 771 insertions(+), 445 deletions(-) create mode 100755 script/build-themes delete mode 100644 styles/buildStyleTree.ts create mode 100644 styles/buildThemes.ts create mode 100644 styles/tsconfig.json create mode 100644 styles/utils/decamelizeTree.ts diff --git a/script/build-themes b/script/build-themes new file mode 100755 index 0000000000000000000000000000000000000000..aef3a4250cdac8a3934938e812d5c7602d388731 --- /dev/null +++ b/script/build-themes @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +cd styles +npm install +npm run build diff --git a/styles/buildStyleTree.ts b/styles/buildStyleTree.ts deleted file mode 100644 index 6fa1c1576d96f312c79b52d15ce2429f3902ff8a..0000000000000000000000000000000000000000 --- a/styles/buildStyleTree.ts +++ /dev/null @@ -1,11 +0,0 @@ -import dark from "./themes/dark"; -import light from "./themes/light"; -import app from "./styleTree/app"; - -for (let theme of [dark, light]) { - let styleTree = app(theme); - - let styleTreeJson = JSON.stringify(styleTree); - console.log(styleTreeJson); - // TODO: Write style tree json to zed crate assets folder -} \ No newline at end of file diff --git a/styles/buildThemes.ts b/styles/buildThemes.ts new file mode 100644 index 0000000000000000000000000000000000000000..ced82e98664980b3d1af9f50d8f4f8f498f59d49 --- /dev/null +++ b/styles/buildThemes.ts @@ -0,0 +1,17 @@ +import * as fs from "fs"; +import * as path from "path"; +import dark from "./themes/dark"; +import light from "./themes/light"; +import app from "./styleTree/app"; +import decamelizeTree from "./utils/decamelizeTree"; + +const themes = [dark, light]; +for (let theme of themes) { + let styleTree = decamelizeTree(app(theme)); + let styleTreeJSON = JSON.stringify(styleTree, null, 2); + let outPath = path.resolve( + `${__dirname}/../crates/zed/assets/themes/${theme.name}.json` + ); + fs.writeFileSync(outPath, styleTreeJSON); + console.log(`Generated ${outPath}`); +} diff --git a/styles/package-lock.json b/styles/package-lock.json index 7b8503bf720d572d64bb9179a78489beaa068cb4..582f1c84968a5c1a25ddac5fd3c21ba907353c6d 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -10,30 +10,307 @@ "license": "ISC", "dependencies": { "@types/chroma-js": "^2.1.3", - "chroma-js": "^2.4.2" + "@types/node": "^17.0.23", + "case-anything": "^2.1.10", + "chroma-js": "^2.4.2", + "ts-node": "^10.7.0" } }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, "node_modules/@types/chroma-js": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/case-anything": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz", + "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ==", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } } }, "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, "@types/chroma-js": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "case-anything": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz", + "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ==" + }, "chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "peer": true + }, + "v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/styles/package.json b/styles/package.json index c66da8718b6d4f2047cbc4e7580036946dab1fb8..c270bba0e1563cee758bbf5a02fb9fc1848b37ae 100644 --- a/styles/package.json +++ b/styles/package.json @@ -4,12 +4,15 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "ts-node buildThemes.ts" }, "author": "", "license": "ISC", "dependencies": { "@types/chroma-js": "^2.1.3", - "chroma-js": "^2.4.2" + "@types/node": "^17.0.23", + "case-anything": "^2.1.10", + "chroma-js": "^2.4.2", + "ts-node": "^10.7.0" } } diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index 098677a1e91c898e1e57624fa28a39fe9bbafee9..42f80cf4c670deda733f434c3cbab691239f5396 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -4,246 +4,246 @@ import Theme, { NumberToken, Syntax } from "./theme"; const { color } = core; const backgroundColor = { - 100: { - base: color.neutral[750], - hovered: color.neutral[750], - active: color.neutral[750], - focused: color.neutral[750], - }, - 300: { - base: color.neutral[800], - hovered: color.neutral[800], - active: color.neutral[800], - focused: color.neutral[800], - }, - 500: { - base: color.neutral[900], - hovered: color.neutral[900], - active: color.neutral[900], - focused: color.neutral[900], - }, - ok: { - base: color.green[600], - hovered: color.green[600], - active: color.green[600], - focused: color.green[600], - }, - error: { - base: color.red[400], - hovered: color.red[400], - active: color.red[400], - focused: color.red[400], - }, - warning: { - base: color.amber[300], - hovered: color.amber[300], - active: color.amber[300], - focused: color.amber[300], - }, - info: { - base: color.blue[500], - hovered: color.blue[500], - active: color.blue[500], - focused: color.blue[500], - }, + 100: { + base: color.neutral[750], + hovered: color.neutral[750], + active: color.neutral[750], + focused: color.neutral[750], + }, + 300: { + base: color.neutral[800], + hovered: color.neutral[800], + active: color.neutral[800], + focused: color.neutral[800], + }, + 500: { + base: color.neutral[900], + hovered: color.neutral[900], + active: color.neutral[900], + focused: color.neutral[900], + }, + ok: { + base: color.green[600], + hovered: color.green[600], + active: color.green[600], + focused: color.green[600], + }, + error: { + base: color.red[400], + hovered: color.red[400], + active: color.red[400], + focused: color.red[400], + }, + warning: { + base: color.amber[300], + hovered: color.amber[300], + active: color.amber[300], + focused: color.amber[300], + }, + info: { + base: color.blue[500], + hovered: color.blue[500], + active: color.blue[500], + focused: color.blue[500], + }, }; const borderColor = { - primary: color.neutral[850], - secondary: color.neutral[700], - muted: color.neutral[750], - focused: color.neutral[100], - active: color.neutral[500], - ok: color.neutral[999], - error: color.neutral[999], - warning: color.neutral[999], - info: color.neutral[999], + primary: color.neutral[850], + secondary: color.neutral[700], + muted: color.neutral[750], + focused: color.neutral[100], + active: color.neutral[500], + ok: color.neutral[1000], + error: color.neutral[1000], + warning: color.neutral[1000], + info: color.neutral[1000], }; const textColor = { - primary: color.neutral[150], - secondary: color.neutral[350], - muted: color.neutral[550], - placeholder: color.neutral[750], - active: color.neutral[0], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: color.neutral[150], + secondary: color.neutral[350], + muted: color.neutral[550], + placeholder: color.neutral[750], + active: color.neutral[0], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const iconColor = { - primary: color.neutral[300], - secondary: color.neutral[500], - muted: color.neutral[600], - placeholder: color.neutral[700], - active: color.neutral[50], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: color.neutral[300], + secondary: color.neutral[500], + muted: color.neutral[600], + placeholder: color.neutral[700], + active: color.neutral[50], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const player = { - 1: { - baseColor: color.blue[600], - cursorColor: color.blue[600], - selectionColor: color.blue[600], - borderColor: color.blue[600], - }, - 2: { - baseColor: color.indigo[500], - cursorColor: color.indigo[500], - selectionColor: color.indigo[500], - borderColor: color.indigo[500], - }, - 3: { - baseColor: color.green[500], - cursorColor: color.green[500], - selectionColor: color.green[500], - borderColor: color.green[500], - }, - 4: { - baseColor: color.orange[500], - cursorColor: color.orange[500], - selectionColor: color.orange[500], - borderColor: color.orange[500], - }, - 5: { - baseColor: color.purple[500], - cursorColor: color.purple[500], - selectionColor: color.purple[500], - borderColor: color.purple[500], - }, - 6: { - baseColor: color.teal[400], - cursorColor: color.teal[400], - selectionColor: color.teal[400], - borderColor: color.teal[400], - }, - 7: { - baseColor: color.pink[400], - cursorColor: color.pink[400], - selectionColor: color.pink[400], - borderColor: color.pink[400], - }, - 8: { - baseColor: color.yellow[400], - cursorColor: color.yellow[400], - selectionColor: color.yellow[400], - borderColor: color.yellow[400], - }, + 1: { + baseColor: color.blue[600], + cursorColor: color.blue[600], + selectionColor: color.blue[600], + borderColor: color.blue[600], + }, + 2: { + baseColor: color.indigo[500], + cursorColor: color.indigo[500], + selectionColor: color.indigo[500], + borderColor: color.indigo[500], + }, + 3: { + baseColor: color.green[500], + cursorColor: color.green[500], + selectionColor: color.green[500], + borderColor: color.green[500], + }, + 4: { + baseColor: color.orange[500], + cursorColor: color.orange[500], + selectionColor: color.orange[500], + borderColor: color.orange[500], + }, + 5: { + baseColor: color.purple[500], + cursorColor: color.purple[500], + selectionColor: color.purple[500], + borderColor: color.purple[500], + }, + 6: { + baseColor: color.teal[400], + cursorColor: color.teal[400], + selectionColor: color.teal[400], + borderColor: color.teal[400], + }, + 7: { + baseColor: color.pink[400], + cursorColor: color.pink[400], + selectionColor: color.pink[400], + borderColor: color.pink[400], + }, + 8: { + baseColor: color.yellow[400], + cursorColor: color.yellow[400], + selectionColor: color.yellow[400], + borderColor: color.yellow[400], + }, }; // TODO: Fixup const editor = { - background: backgroundColor[500].base, - indent_guide: borderColor.muted, - indent_guide_active: borderColor.secondary, - line: { - active: color.neutral[0], - highlighted: color.neutral[0], - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, - }, - highlight: { - selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: color.neutral[0], - matchingBracket: color.neutral[0], - match: color.neutral[0], - activeMatch: color.neutral[0], - related: color.neutral[0], - }, - gutter: { - primary: color.neutral[0], - active: color.neutral[0], - }, + background: backgroundColor[500].base, + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, + line: { + active: color.neutral[0], + highlighted: color.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, + }, + highlight: { + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: color.neutral[0], + matchingBracket: color.neutral[0], + match: color.neutral[0], + activeMatch: color.neutral[0], + related: color.neutral[0], + }, + gutter: { + primary: color.neutral[0], + active: color.neutral[0], + }, }; const syntax: Syntax = { - primary: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - comment: { - color: color.lime[200], - weight: { value: "normal", type: "fontWeight" }, - }, - punctuation: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - constant: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - keyword: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - function: { - color: color.yellow[200], - weight: { value: "normal", type: "fontWeight" }, - }, - type: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - variant: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - property: { - color: color.sky[300], - weight: { value: "normal", type: "fontWeight" }, - }, - enum: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - operator: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - string: { - color: color.orange[300], - weight: { value: "normal", type: "fontWeight" }, - }, - number: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - boolean: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - predictive: { - color: textColor.muted, - weight: { value: "normal", type: "fontWeight" }, - }, + primary: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + comment: { + color: color.lime[200], + weight: { value: "normal", type: "fontWeight" }, + }, + punctuation: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + constant: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + keyword: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + function: { + color: color.yellow[200], + weight: { value: "normal", type: "fontWeight" }, + }, + type: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + variant: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + property: { + color: color.sky[300], + weight: { value: "normal", type: "fontWeight" }, + }, + enum: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + operator: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + string: { + color: color.orange[300], + weight: { value: "normal", type: "fontWeight" }, + }, + number: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + boolean: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + predictive: { + color: textColor.muted, + weight: { value: "normal", type: "fontWeight" }, + }, }; const shadowAlpha: NumberToken = { - value: 0.32, - type: "number" + value: 0.32, + type: "number", }; const theme: Theme = { - name: "dark", - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, + name: "dark", + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, }; -export default theme; \ No newline at end of file +export default theme; diff --git a/styles/themes/light.ts b/styles/themes/light.ts index 20760427f273e93d72c2cf7cee6a8c0f6ae7192d..7a9bf1b552650b81288e70acc6c7500c80a8246b 100644 --- a/styles/themes/light.ts +++ b/styles/themes/light.ts @@ -6,246 +6,246 @@ const { color } = core; // TODO: Replace with light values const backgroundColor = { - 100: { - base: color.neutral[750], - hovered: color.neutral[750], - active: color.neutral[750], - focused: color.neutral[750], - }, - 300: { - base: color.neutral[800], - hovered: color.neutral[800], - active: color.neutral[800], - focused: color.neutral[800], - }, - 500: { - base: color.neutral[900], - hovered: color.neutral[900], - active: color.neutral[900], - focused: color.neutral[900], - }, - ok: { - base: color.green[600], - hovered: color.green[600], - active: color.green[600], - focused: color.green[600], - }, - error: { - base: color.red[400], - hovered: color.red[400], - active: color.red[400], - focused: color.red[400], - }, - warning: { - base: color.amber[300], - hovered: color.amber[300], - active: color.amber[300], - focused: color.amber[300], - }, - info: { - base: color.blue[500], - hovered: color.blue[500], - active: color.blue[500], - focused: color.blue[500], - }, + 100: { + base: color.neutral[750], + hovered: color.neutral[750], + active: color.neutral[750], + focused: color.neutral[750], + }, + 300: { + base: color.neutral[800], + hovered: color.neutral[800], + active: color.neutral[800], + focused: color.neutral[800], + }, + 500: { + base: color.neutral[900], + hovered: color.neutral[900], + active: color.neutral[900], + focused: color.neutral[900], + }, + ok: { + base: color.green[600], + hovered: color.green[600], + active: color.green[600], + focused: color.green[600], + }, + error: { + base: color.red[400], + hovered: color.red[400], + active: color.red[400], + focused: color.red[400], + }, + warning: { + base: color.amber[300], + hovered: color.amber[300], + active: color.amber[300], + focused: color.amber[300], + }, + info: { + base: color.blue[500], + hovered: color.blue[500], + active: color.blue[500], + focused: color.blue[500], + }, }; const borderColor = { - primary: color.neutral[850], - secondary: color.neutral[700], - muted: color.neutral[750], - focused: color.neutral[100], - active: color.neutral[500], - ok: color.neutral[999], - error: color.neutral[999], - warning: color.neutral[999], - info: color.neutral[999], + primary: color.neutral[850], + secondary: color.neutral[700], + muted: color.neutral[750], + focused: color.neutral[100], + active: color.neutral[500], + ok: color.neutral[1000], + error: color.neutral[1000], + warning: color.neutral[1000], + info: color.neutral[1000], }; const textColor = { - primary: color.neutral[150], - secondary: color.neutral[350], - muted: color.neutral[550], - placeholder: color.neutral[750], - active: color.neutral[0], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: color.neutral[150], + secondary: color.neutral[350], + muted: color.neutral[550], + placeholder: color.neutral[750], + active: color.neutral[0], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const iconColor = { - primary: color.neutral[300], - secondary: color.neutral[500], - muted: color.neutral[600], - placeholder: color.neutral[700], - active: color.neutral[50], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: color.neutral[300], + secondary: color.neutral[500], + muted: color.neutral[600], + placeholder: color.neutral[700], + active: color.neutral[50], + //TODO: (design) define feature and it's correct value + feature: color.sky[500], + ok: color.green[600], + error: color.red[400], + warning: color.amber[300], + info: color.blue[500], }; const player = { - 1: { - baseColor: color.blue[600], - cursorColor: color.blue[600], - selectionColor: color.blue[600], - borderColor: color.blue[600], - }, - 2: { - baseColor: color.indigo[500], - cursorColor: color.indigo[500], - selectionColor: color.indigo[500], - borderColor: color.indigo[500], - }, - 3: { - baseColor: color.green[500], - cursorColor: color.green[500], - selectionColor: color.green[500], - borderColor: color.green[500], - }, - 4: { - baseColor: color.orange[500], - cursorColor: color.orange[500], - selectionColor: color.orange[500], - borderColor: color.orange[500], - }, - 5: { - baseColor: color.purple[500], - cursorColor: color.purple[500], - selectionColor: color.purple[500], - borderColor: color.purple[500], - }, - 6: { - baseColor: color.teal[400], - cursorColor: color.teal[400], - selectionColor: color.teal[400], - borderColor: color.teal[400], - }, - 7: { - baseColor: color.pink[400], - cursorColor: color.pink[400], - selectionColor: color.pink[400], - borderColor: color.pink[400], - }, - 8: { - baseColor: color.yellow[400], - cursorColor: color.yellow[400], - selectionColor: color.yellow[400], - borderColor: color.yellow[400], - }, + 1: { + baseColor: color.blue[600], + cursorColor: color.blue[600], + selectionColor: color.blue[600], + borderColor: color.blue[600], + }, + 2: { + baseColor: color.indigo[500], + cursorColor: color.indigo[500], + selectionColor: color.indigo[500], + borderColor: color.indigo[500], + }, + 3: { + baseColor: color.green[500], + cursorColor: color.green[500], + selectionColor: color.green[500], + borderColor: color.green[500], + }, + 4: { + baseColor: color.orange[500], + cursorColor: color.orange[500], + selectionColor: color.orange[500], + borderColor: color.orange[500], + }, + 5: { + baseColor: color.purple[500], + cursorColor: color.purple[500], + selectionColor: color.purple[500], + borderColor: color.purple[500], + }, + 6: { + baseColor: color.teal[400], + cursorColor: color.teal[400], + selectionColor: color.teal[400], + borderColor: color.teal[400], + }, + 7: { + baseColor: color.pink[400], + cursorColor: color.pink[400], + selectionColor: color.pink[400], + borderColor: color.pink[400], + }, + 8: { + baseColor: color.yellow[400], + cursorColor: color.yellow[400], + selectionColor: color.yellow[400], + borderColor: color.yellow[400], + }, }; // TODO: Fixup const editor = { - background: backgroundColor[500].base, - indent_guide: borderColor.muted, - indent_guide_active: borderColor.secondary, - line: { - active: color.neutral[0], - highlighted: color.neutral[0], - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, - }, - highlight: { - selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: color.neutral[0], - matchingBracket: color.neutral[0], - match: color.neutral[0], - activeMatch: color.neutral[0], - related: color.neutral[0], - }, - gutter: { - primary: color.neutral[0], - active: color.neutral[0], - }, + background: backgroundColor[500].base, + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, + line: { + active: color.neutral[0], + highlighted: color.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, + }, + highlight: { + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: color.neutral[0], + matchingBracket: color.neutral[0], + match: color.neutral[0], + activeMatch: color.neutral[0], + related: color.neutral[0], + }, + gutter: { + primary: color.neutral[0], + active: color.neutral[0], + }, }; const syntax: Syntax = { - primary: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - comment: { - color: color.lime[200], - weight: { value: "normal", type: "fontWeight" }, - }, - punctuation: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - constant: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - keyword: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - function: { - color: color.yellow[200], - weight: { value: "normal", type: "fontWeight" }, - }, - type: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - variant: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - property: { - color: color.sky[300], - weight: { value: "normal", type: "fontWeight" }, - }, - enum: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - operator: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - string: { - color: color.orange[300], - weight: { value: "normal", type: "fontWeight" }, - }, - number: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - boolean: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - predictive: { - color: textColor.muted, - weight: { value: "normal", type: "fontWeight" }, - }, + primary: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + comment: { + color: color.lime[200], + weight: { value: "normal", type: "fontWeight" }, + }, + punctuation: { + color: textColor.primary, + weight: { value: "normal", type: "fontWeight" }, + }, + constant: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + keyword: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + function: { + color: color.yellow[200], + weight: { value: "normal", type: "fontWeight" }, + }, + type: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + variant: { + color: color.teal[300], + weight: { value: "normal", type: "fontWeight" }, + }, + property: { + color: color.sky[300], + weight: { value: "normal", type: "fontWeight" }, + }, + enum: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + operator: { + color: color.sky[400], + weight: { value: "normal", type: "fontWeight" }, + }, + string: { + color: color.orange[300], + weight: { value: "normal", type: "fontWeight" }, + }, + number: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + boolean: { + color: color.neutral[150], + weight: { value: "normal", type: "fontWeight" }, + }, + predictive: { + color: textColor.muted, + weight: { value: "normal", type: "fontWeight" }, + }, }; const shadowAlpha: NumberToken = { - value: 0.32, - type: "number" + value: 0.32, + type: "number", }; const theme: Theme = { - name: "light", - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, + name: "light", + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, }; export default theme; diff --git a/styles/tsconfig.json b/styles/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..3dfbcc715ef17318d9267709bb8f25a8b91ecac0 --- /dev/null +++ b/styles/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2015", + "module": "commonjs", + "esModuleInterop": true, + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true + }, + "exclude": ["node_modules"] + } \ No newline at end of file diff --git a/styles/utils/decamelizeTree.ts b/styles/utils/decamelizeTree.ts new file mode 100644 index 0000000000000000000000000000000000000000..d606902082e974b6cb7b0602e06cc32b0a9e1b5f --- /dev/null +++ b/styles/utils/decamelizeTree.ts @@ -0,0 +1,21 @@ +import { snakeCase } from "case-anything"; + +export default function decamelizeTree(object: { [key: string]: any }) { + const snakeObject: { [key: string]: any } = {}; + for (const key in object) { + snakeObject[snakeCase(key)] = decamelizeValue(object[key]); + } + return snakeObject; +} + +function decamelizeValue(value: any): any { + if (typeof value === "object") { + if (Array.isArray(value)) { + return value.map(decamelizeValue); + } else { + return decamelizeTree(value); + } + } else { + return value; + } +} From 371ea7c5529aa670e9b5aded82b2762be6073a38 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 1 Apr 2022 09:56:50 -0600 Subject: [PATCH 57/68] Update style tree based on changes to _base.toml from main Co-Authored-By: Nate Butler <1714999+iamnbutler@users.noreply.github.com> --- styles/styleTree/search.ts | 15 ++++++--------- styles/styleTree/workspace.ts | 10 +++++++++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/styles/styleTree/search.ts b/styles/styleTree/search.ts index fd2fd2568156f31a877de40773b9382eb5a8e6ca..7ba04cd688e01f5b3a4f47b35311195fde73fefb 100644 --- a/styles/styleTree/search.ts +++ b/styles/styleTree/search.ts @@ -20,7 +20,6 @@ export default function search(theme: Theme) { }; return { - background: backgroundColor(theme, 300), matchBackground: theme.editor.highlight.match, tabIconSpacing: 4, tabIconWidth: 14, @@ -35,22 +34,20 @@ export default function search(theme: Theme) { editor: { background: backgroundColor(theme, 500), cornerRadius: 6, - maxWidth: 400, + minWidth: 200, + maxWidth: 500, placeholderText: text(theme, "mono", "placeholder"), selection: player(theme, 1).selection, text: text(theme, "mono", "primary"), border: border(theme, "primary"), margin: { - bottom: 5, - left: 5, right: 5, - top: 5, }, padding: { - bottom: 3, - left: 13, - right: 13, top: 3, + bottom: 3, + left: 14, + right: 14, }, }, hoveredOptionButton: { @@ -62,7 +59,7 @@ export default function search(theme: Theme) { border: border(theme, "error"), }, matchIndex: { - ...text(theme, "mono", "secondary"), + ...text(theme, "mono", "muted"), padding: 6, }, optionButton, diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index e8232442b6f01ec2d0e3486509218f4b4c9e7562..148db089183e77274a81a122d6f02d920b640237 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -127,7 +127,15 @@ export default function workspace(theme: Theme) { }, }, toolbar: { - height: 44, + height: 34, + background: backgroundColor(theme, 300), + border: border(theme, "primary", { bottom: true }), + itemSpacing: 8, + padding: { left: 16, right: 8, top: 4, bottom: 4 }, + }, + breadcrumbs: { + ...text(theme, "mono", "secondary"), + padding: { left: 6 }, }, }; } From 391aed3d66c194e5c66781fdec736c577a0c347e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 1 Apr 2022 11:45:08 -0600 Subject: [PATCH 58/68] Start loading new theme JSON format instead of TOML Replaced remaining extends with javascript object extension. Moved tokens/core.ts to tokens.ts and massaged the types to make it more obvious when types don't match up. Co-authored-by: Nathan Sobo --- crates/theme/src/resolution.rs | 497 ----------- crates/theme/src/theme.rs | 3 +- crates/theme/src/theme_registry.rs | 234 +---- crates/zed/assets/themes/_base.toml | 411 --------- crates/zed/assets/themes/black.toml | 67 -- crates/zed/assets/themes/dark.json | 1245 +++++++++++++++++++++++++++ crates/zed/assets/themes/dark.toml | 67 -- crates/zed/assets/themes/light.json | 1245 +++++++++++++++++++++++++++ crates/zed/assets/themes/light.toml | 67 -- crates/zed/src/zed.rs | 3 +- styles/buildThemes.ts | 14 +- styles/styleTree/app.ts | 106 +-- styles/styleTree/components.ts | 14 +- styles/styleTree/contactsPanel.ts | 61 ++ styles/styleTree/editor.ts | 245 +++--- styles/styleTree/projectPanel.ts | 6 +- styles/styleTree/search.ts | 44 +- styles/styleTree/workspace.ts | 5 + styles/themes/dark.ts | 462 +++++----- styles/themes/light.ts | 300 ++++--- styles/themes/theme.ts | 37 +- styles/tokens.ts | 102 +++ styles/tokens/core.ts | 58 -- 23 files changed, 3284 insertions(+), 2009 deletions(-) delete mode 100644 crates/theme/src/resolution.rs delete mode 100644 crates/zed/assets/themes/_base.toml delete mode 100644 crates/zed/assets/themes/black.toml create mode 100644 crates/zed/assets/themes/dark.json delete mode 100644 crates/zed/assets/themes/dark.toml create mode 100644 crates/zed/assets/themes/light.json delete mode 100644 crates/zed/assets/themes/light.toml create mode 100644 styles/styleTree/contactsPanel.ts create mode 100644 styles/tokens.ts delete mode 100644 styles/tokens/core.ts diff --git a/crates/theme/src/resolution.rs b/crates/theme/src/resolution.rs deleted file mode 100644 index acebf72b86120065cb8587d05c2a8db92a00cced..0000000000000000000000000000000000000000 --- a/crates/theme/src/resolution.rs +++ /dev/null @@ -1,497 +0,0 @@ -use anyhow::{anyhow, Result}; -use indexmap::IndexMap; -use serde_json::Value; -use std::{ - cell::RefCell, - mem, - rc::{Rc, Weak}, -}; - -pub fn resolve_references(value: Value) -> Result { - let tree = Tree::from_json(value)?; - tree.resolve()?; - tree.to_json() -} - -#[derive(Clone)] -enum Node { - Reference { - path: String, - parent: Option>>, - }, - Object { - base: Option, - children: IndexMap, - resolved: bool, - parent: Option>>, - }, - Array { - children: Vec, - resolved: bool, - parent: Option>>, - }, - String { - value: String, - parent: Option>>, - }, - Number { - value: serde_json::Number, - parent: Option>>, - }, - Bool { - value: bool, - parent: Option>>, - }, - Null { - parent: Option>>, - }, -} - -#[derive(Clone)] -struct Tree(Rc>); - -impl Tree { - pub fn new(node: Node) -> Self { - Self(Rc::new(RefCell::new(node))) - } - - fn from_json(value: Value) -> Result { - match value { - Value::String(value) => { - if let Some(path) = value.strip_prefix("$") { - Ok(Self::new(Node::Reference { - path: path.to_string(), - parent: None, - })) - } else { - Ok(Self::new(Node::String { - value, - parent: None, - })) - } - } - Value::Number(value) => Ok(Self::new(Node::Number { - value, - parent: None, - })), - Value::Bool(value) => Ok(Self::new(Node::Bool { - value, - parent: None, - })), - Value::Null => Ok(Self::new(Node::Null { parent: None })), - Value::Object(object) => { - let tree = Self::new(Node::Object { - base: Default::default(), - children: Default::default(), - resolved: false, - parent: None, - }); - let mut children = IndexMap::new(); - let mut resolved = true; - let mut base = None; - for (key, value) in object.into_iter() { - let value = if key == "extends" { - if value.is_string() { - if let Value::String(value) = value { - base = value.strip_prefix("$").map(str::to_string); - resolved = false; - Self::new(Node::String { - value, - parent: None, - }) - } else { - unreachable!() - } - } else { - Tree::from_json(value)? - } - } else { - Tree::from_json(value)? - }; - value - .0 - .borrow_mut() - .set_parent(Some(Rc::downgrade(&tree.0))); - resolved &= value.is_resolved(); - children.insert(key.clone(), value); - } - - *tree.0.borrow_mut() = Node::Object { - base, - children, - resolved, - parent: None, - }; - Ok(tree) - } - Value::Array(elements) => { - let tree = Self::new(Node::Array { - children: Default::default(), - resolved: false, - parent: None, - }); - - let mut children = Vec::new(); - let mut resolved = true; - for element in elements { - let child = Tree::from_json(element)?; - child - .0 - .borrow_mut() - .set_parent(Some(Rc::downgrade(&tree.0))); - resolved &= child.is_resolved(); - children.push(child); - } - - *tree.0.borrow_mut() = Node::Array { - children, - resolved, - parent: None, - }; - Ok(tree) - } - } - } - - fn to_json(&self) -> Result { - match &*self.0.borrow() { - Node::Reference { .. } => Err(anyhow!("unresolved tree")), - Node::String { value, .. } => Ok(Value::String(value.clone())), - Node::Number { value, .. } => Ok(Value::Number(value.clone())), - Node::Bool { value, .. } => Ok(Value::Bool(*value)), - Node::Null { .. } => Ok(Value::Null), - Node::Object { children, .. } => { - let mut json_children = serde_json::Map::new(); - for (key, value) in children { - json_children.insert(key.clone(), value.to_json()?); - } - Ok(Value::Object(json_children)) - } - Node::Array { children, .. } => { - let mut json_children = Vec::new(); - for child in children { - json_children.push(child.to_json()?); - } - Ok(Value::Array(json_children)) - } - } - } - - fn parent(&self) -> Option { - match &*self.0.borrow() { - Node::Reference { parent, .. } - | Node::Object { parent, .. } - | Node::Array { parent, .. } - | Node::String { parent, .. } - | Node::Number { parent, .. } - | Node::Bool { parent, .. } - | Node::Null { parent } => parent.as_ref().and_then(|p| p.upgrade()).map(Tree), - } - } - - fn get(&self, path: &str) -> Result> { - let mut tree = self.clone(); - for component in path.split('.') { - let node = tree.0.borrow(); - match &*node { - Node::Object { children, .. } => { - if let Some(subtree) = children.get(component).cloned() { - drop(node); - tree = subtree; - } else { - return Err(anyhow!( - "key \"{}\" does not exist in path \"{}\"", - component, - path - )); - } - } - Node::Reference { .. } => return Ok(None), - Node::Array { .. } - | Node::String { .. } - | Node::Number { .. } - | Node::Bool { .. } - | Node::Null { .. } => { - return Err(anyhow!( - "key \"{}\" in path \"{}\" is not an object", - component, - path - )) - } - } - } - - Ok(Some(tree)) - } - - fn is_resolved(&self) -> bool { - match &*self.0.borrow() { - Node::Reference { .. } => false, - Node::Object { resolved, .. } | Node::Array { resolved, .. } => *resolved, - Node::String { .. } | Node::Number { .. } | Node::Bool { .. } | Node::Null { .. } => { - true - } - } - } - - fn update_resolved(&self) { - match &mut *self.0.borrow_mut() { - Node::Object { - resolved, - base, - children, - .. - } => { - *resolved = base.is_none() && children.values().all(|c| c.is_resolved()); - } - Node::Array { - resolved, children, .. - } => { - *resolved = children.iter().all(|c| c.is_resolved()); - } - _ => {} - } - } - - pub fn resolve(&self) -> Result<()> { - let mut unresolved = vec![self.clone()]; - let mut made_progress = true; - - while made_progress && !unresolved.is_empty() { - made_progress = false; - for mut tree in mem::take(&mut unresolved) { - made_progress |= tree.resolve_subtree(self, &mut unresolved)?; - if tree.is_resolved() { - while let Some(parent) = tree.parent() { - parent.update_resolved(); - if !parent.is_resolved() { - break; - } - tree = parent; - } - } - } - } - - if unresolved.is_empty() { - Ok(()) - } else { - Err(anyhow!("tree contains cycles")) - } - } - - fn resolve_subtree(&self, root: &Tree, unresolved: &mut Vec) -> Result { - let node = self.0.borrow(); - match &*node { - Node::Reference { path, parent } => { - if let Some(subtree) = root.get(&path)? { - if subtree.is_resolved() { - let parent = parent.clone(); - drop(node); - let mut new_node = subtree.0.borrow().clone(); - new_node.set_parent(parent); - *self.0.borrow_mut() = new_node; - Ok(true) - } else { - unresolved.push(self.clone()); - Ok(false) - } - } else { - unresolved.push(self.clone()); - Ok(false) - } - } - Node::Object { - base, - children, - resolved, - .. - } => { - if *resolved { - Ok(false) - } else { - let mut made_progress = false; - let mut children_resolved = true; - for child in children.values() { - made_progress |= child.resolve_subtree(root, unresolved)?; - children_resolved &= child.is_resolved(); - } - - if children_resolved { - let mut has_base = false; - let mut resolved_base = None; - if let Some(base) = base { - has_base = true; - if let Some(base) = root.get(base)? { - if base.is_resolved() { - resolved_base = Some(base); - } - } - } - - drop(node); - - if let Some(base) = resolved_base.as_ref() { - self.extend_from(&base); - made_progress = true; - } - - if let Node::Object { resolved, base, .. } = &mut *self.0.borrow_mut() { - if has_base { - if resolved_base.is_some() { - base.take(); - *resolved = true; - } else { - unresolved.push(self.clone()); - } - } else { - *resolved = true; - } - } - } else if base.is_some() { - unresolved.push(self.clone()); - } - - Ok(made_progress) - } - } - Node::Array { - children, resolved, .. - } => { - if *resolved { - Ok(false) - } else { - let mut made_progress = false; - let mut children_resolved = true; - for child in children.iter() { - made_progress |= child.resolve_subtree(root, unresolved)?; - children_resolved &= child.is_resolved(); - } - - if children_resolved { - drop(node); - - if let Node::Array { resolved, .. } = &mut *self.0.borrow_mut() { - *resolved = true; - } - } - - Ok(made_progress) - } - } - Node::String { .. } | Node::Number { .. } | Node::Bool { .. } | Node::Null { .. } => { - Ok(false) - } - } - } - - fn extend_from(&self, base: &Tree) { - if Rc::ptr_eq(&self.0, &base.0) { - return; - } - - if let ( - Node::Object { children, .. }, - Node::Object { - children: base_children, - .. - }, - ) = (&mut *self.0.borrow_mut(), &*base.0.borrow()) - { - for (key, base_value) in base_children { - if let Some(value) = children.get(key) { - value.extend_from(base_value); - } else { - let base_value = base_value.clone(); - base_value - .0 - .borrow_mut() - .set_parent(Some(Rc::downgrade(&self.0))); - children.insert(key.clone(), base_value); - } - } - } - } -} - -impl Node { - fn set_parent(&mut self, new_parent: Option>>) { - match self { - Node::Reference { parent, .. } - | Node::Object { parent, .. } - | Node::Array { parent, .. } - | Node::String { parent, .. } - | Node::Number { parent, .. } - | Node::Bool { parent, .. } - | Node::Null { parent } => *parent = new_parent, - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_references() { - let json = serde_json::json!({ - "a": { - "extends": "$g", - "x": "$b.d" - }, - "b": { - "c": "$a", - "d": "$e.f" - }, - "e": { - "extends": "$a", - "f": "1" - }, - "g": { - "h": 2 - } - }); - - assert_eq!( - resolve_references(json).unwrap(), - serde_json::json!({ - "a": { - "extends": "$g", - "x": "1", - "h": 2 - }, - "b": { - "c": { - "extends": "$g", - "x": "1", - "h": 2 - }, - "d": "1" - }, - "e": { - "extends": "$a", - "f": "1", - "x": "1", - "h": 2 - }, - "g": { - "h": 2 - } - }) - ) - } - - #[test] - fn test_cycles() { - let json = serde_json::json!({ - "a": { - "b": "$c.d" - }, - "c": { - "d": "$a.b", - }, - }); - - assert!(resolve_references(json).is_err()); - } -} diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 8fa15a92359c18ff7986978d66088c4f6a9332c1..b3c239b4b9f119159f76a3ed23ec477069c6bbd8 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -1,4 +1,3 @@ -mod resolution; mod theme_registry; use gpui::{ @@ -12,7 +11,7 @@ use std::{collections::HashMap, sync::Arc}; pub use theme_registry::*; -pub const DEFAULT_THEME_NAME: &'static str = "black"; +pub const DEFAULT_THEME_NAME: &'static str = "dark"; #[derive(Deserialize, Default)] pub struct Theme { diff --git a/crates/theme/src/theme_registry.rs b/crates/theme/src/theme_registry.rs index c3910dc4d28f6877b326b4fda36e59d2922db17c..219828b65083b08f1d7d0a105831acfc27bdf50a 100644 --- a/crates/theme/src/theme_registry.rs +++ b/crates/theme/src/theme_registry.rs @@ -1,8 +1,8 @@ -use crate::{resolution::resolve_references, Theme}; +use crate::Theme; use anyhow::{Context, Result}; use gpui::{fonts, AssetSource, FontCache}; use parking_lot::Mutex; -use serde_json::{Map, Value}; +use serde_json::Value; use std::{collections::HashMap, sync::Arc}; pub struct ThemeRegistry { @@ -25,12 +25,8 @@ impl ThemeRegistry { pub fn list(&self) -> impl Iterator { self.assets.list("themes/").into_iter().filter_map(|path| { let filename = path.strip_prefix("themes/")?; - let theme_name = filename.strip_suffix(".toml")?; - if theme_name.starts_with('_') { - None - } else { - Some(theme_name.to_string()) - } + let theme_name = filename.strip_suffix(".json")?; + Some(theme_name.to_string()) }) } @@ -44,9 +40,14 @@ impl ThemeRegistry { return Ok(theme.clone()); } - let theme_data = self.load(name, true)?; + let asset_path = format!("themes/{}.json", name); + let theme_json = self + .assets + .load(&asset_path) + .with_context(|| format!("failed to load theme file {}", asset_path))?; + let mut theme: Theme = fonts::with_font_cache(self.font_cache.clone(), || { - serde_path_to_error::deserialize(theme_data.as_ref()) + serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_slice(&theme_json)) })?; theme.name = name.into(); @@ -54,217 +55,4 @@ impl ThemeRegistry { self.themes.lock().insert(name.to_string(), theme.clone()); Ok(theme) } - - fn load(&self, name: &str, evaluate_references: bool) -> Result> { - if let Some(data) = self.theme_data.lock().get(name) { - return Ok(data.clone()); - } - - let asset_path = format!("themes/{}.toml", name); - let source_code = self - .assets - .load(&asset_path) - .with_context(|| format!("failed to load theme file {}", asset_path))?; - - let mut theme_data: Map = toml::from_slice(source_code.as_ref()) - .with_context(|| format!("failed to parse {}.toml", name))?; - - // If this theme extends another base theme, deeply merge it into the base theme's data - if let Some(base_name) = theme_data - .get("extends") - .and_then(|name| name.as_str()) - .map(str::to_string) - { - let base_theme_data = self - .load(&base_name, false) - .with_context(|| format!("failed to load base theme {}", base_name))? - .as_ref() - .clone(); - if let Value::Object(mut base_theme_object) = base_theme_data { - deep_merge_json(&mut base_theme_object, theme_data); - theme_data = base_theme_object; - } - } - - let mut theme_data = Value::Object(theme_data); - - // Find all of the key path references in the object, and then sort them according - // to their dependencies. - if evaluate_references { - theme_data = resolve_references(theme_data)?; - } - - let result = Arc::new(theme_data); - self.theme_data - .lock() - .insert(name.to_string(), result.clone()); - - Ok(result) - } -} - -fn deep_merge_json(base: &mut Map, extension: Map) { - for (key, extension_value) in extension { - if let Value::Object(extension_object) = extension_value { - if let Some(base_object) = base.get_mut(&key).and_then(|value| value.as_object_mut()) { - deep_merge_json(base_object, extension_object); - } else { - base.insert(key, Value::Object(extension_object)); - } - } else { - base.insert(key, extension_value); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use anyhow::anyhow; - use gpui::MutableAppContext; - - #[gpui::test] - fn test_theme_extension(cx: &mut MutableAppContext) { - let assets = TestAssets(&[ - ( - "themes/_base.toml", - r##" - [ui.active_tab] - extends = "$ui.tab" - border.color = "#666666" - text = "$text_colors.bright" - - [ui.tab] - extends = "$ui.element" - text = "$text_colors.dull" - - [ui.element] - background = "#111111" - border = {width = 2.0, color = "#00000000"} - - [editor] - background = "#222222" - default_text = "$text_colors.regular" - "##, - ), - ( - "themes/light.toml", - r##" - extends = "_base" - - [text_colors] - bright = "#ffffff" - regular = "#eeeeee" - dull = "#dddddd" - - [editor] - background = "#232323" - "##, - ), - ]); - - let registry = ThemeRegistry::new(assets, cx.font_cache().clone()); - let theme_data = registry.load("light", true).unwrap(); - - assert_eq!( - theme_data.as_ref(), - &serde_json::json!({ - "ui": { - "active_tab": { - "background": "#111111", - "border": { - "width": 2.0, - "color": "#666666" - }, - "extends": "$ui.tab", - "text": "#ffffff" - }, - "tab": { - "background": "#111111", - "border": { - "width": 2.0, - "color": "#00000000" - }, - "extends": "$ui.element", - "text": "#dddddd" - }, - "element": { - "background": "#111111", - "border": { - "width": 2.0, - "color": "#00000000" - } - } - }, - "editor": { - "background": "#232323", - "default_text": "#eeeeee" - }, - "extends": "_base", - "text_colors": { - "bright": "#ffffff", - "regular": "#eeeeee", - "dull": "#dddddd" - } - }) - ); - } - - #[gpui::test] - fn test_nested_extension(cx: &mut MutableAppContext) { - let assets = TestAssets(&[( - "themes/theme.toml", - r##" - [a] - text = { extends = "$text.0" } - - [b] - extends = "$a" - text = { extends = "$text.1" } - - [text] - 0 = { color = "red" } - 1 = { color = "blue" } - "##, - )]); - - let registry = ThemeRegistry::new(assets, cx.font_cache().clone()); - let theme_data = registry.load("theme", true).unwrap(); - assert_eq!( - theme_data - .get("b") - .unwrap() - .get("text") - .unwrap() - .get("color") - .unwrap(), - "blue" - ); - } - - struct TestAssets(&'static [(&'static str, &'static str)]); - - impl AssetSource for TestAssets { - fn load(&self, path: &str) -> Result> { - if let Some(row) = self.0.iter().find(|e| e.0 == path) { - Ok(row.1.as_bytes().into()) - } else { - Err(anyhow!("no such path {}", path)) - } - } - - fn list(&self, prefix: &str) -> Vec> { - self.0 - .iter() - .copied() - .filter_map(|(path, _)| { - if path.starts_with(prefix) { - Some(path.into()) - } else { - None - } - }) - .collect() - } - } } diff --git a/crates/zed/assets/themes/_base.toml b/crates/zed/assets/themes/_base.toml deleted file mode 100644 index 7f235cbf48e322fc60f1cebee27e7d15a53d7014..0000000000000000000000000000000000000000 --- a/crates/zed/assets/themes/_base.toml +++ /dev/null @@ -1,411 +0,0 @@ -[text] -base = { family = "Zed Sans", size = 14 } - -[workspace] -background = "$surface.0" -pane_divider = { width = 1, color = "$border.0" } -leader_border_opacity = 0.7 -leader_border_width = 2.0 - -[workspace.titlebar] -height = 32 -border = { width = 1, bottom = true, color = "$border.0" } -title = "$text.0" -avatar_width = 18 -avatar = { corner_radius = 10, border = { width = 1, color = "#00000088" } } -avatar_ribbon = { background = "#ff0000", height = 3, width = 12 } -outdated_warning = { extends = "$text.2", size = 13 } -share_icon_color = "$text.2.color" -share_icon_active_color = "$text.0.color" - -[workspace.titlebar.sign_in_prompt] -extends = "$text.2" -size = 13 -underline = true -padding = { right = 8 } - -[workspace.titlebar.hovered_sign_in_prompt] -extends = "$workspace.titlebar.sign_in_prompt" -color = "$text.1.color" - -[workspace.titlebar.offline_icon] -padding = { right = 4 } -width = 16 -color = "$text.2.color" - -[workspace.tab] -height = 34 -text = "$text.2" -padding = { left = 12, right = 12 } -icon_width = 8 -spacing = 10 -icon_close = "$text.2.color" -icon_close_active = "$text.0.color" -icon_dirty = "$status.info" -icon_conflict = "$status.warn" -border = { left = true, bottom = true, width = 1, color = "$border.0", overlay = true } - -[workspace.active_tab] -extends = "$workspace.tab" -border.bottom = false -background = "$surface.1" -text = "$text.0" - -[workspace.sidebar] -width = 30 -border = { right = true, width = 1, color = "$border.0" } - -[workspace.sidebar.resize_handle] -padding = { left = 1 } -background = "$border.0" - -[workspace.sidebar.item] -icon_color = "$text.2.color" -icon_size = 18 -height = "$workspace.tab.height" - -[workspace.sidebar.active_item] -extends = "$workspace.sidebar.item" -icon_color = "$text.0.color" - -[workspace.left_sidebar] -extends = "$workspace.sidebar" -border = { width = 1, color = "$border.0", right = true } - -[workspace.right_sidebar] -extends = "$workspace.sidebar" -border = { width = 1, color = "$border.0", left = true } - -[workspace.status_bar] -padding = { left = 6, right = 6 } -height = 24 -item_spacing = 8 -cursor_position = "$text.2" -diagnostic_message = "$text.2" -lsp_message = "$text.2" - -[workspace.toolbar] -background = "$surface.1" -border = { color = "$border.0", width = 1, left = false, right = false, bottom = true, top = false } -height = 34 -item_spacing = 8 -padding = { left = 16, right = 8, top = 4, bottom = 4 } - -[breadcrumbs] -extends = "$text.1" -padding = { left = 6 } - -[panel] -padding = { top = 12, left = 12, bottom = 12, right = 12 } - -[chat_panel] -extends = "$panel" -channel_name = { extends = "$text.0", weight = "bold" } -channel_name_hash = { text = "$text.2", padding.right = 8 } - -[chat_panel.message] -body = "$text.1" -sender = { extends = "$text.0", weight = "bold", margin.right = 8 } -timestamp = "$text.2" -padding.bottom = 6 - -[chat_panel.pending_message] -extends = "$chat_panel.message" -body = { color = "$text.3.color" } -sender = { color = "$text.3.color" } -timestamp = { color = "$text.3.color" } - -[chat_panel.channel_select.item] -padding = 4 -name = "$text.1" -hash = { extends = "$text.2", margin.right = 8 } - -[chat_panel.channel_select.hovered_item] -extends = "$chat_panel.channel_select.item" -background = "$state.hover" -corner_radius = 6 - -[chat_panel.channel_select.active_item] -extends = "$chat_panel.channel_select.item" -name = "$text.0" - -[chat_panel.channel_select.hovered_active_item] -extends = "$chat_panel.channel_select.hovered_item" -name = "$text.0" - -[chat_panel.channel_select.header] -extends = "$chat_panel.channel_select.active_item" -padding.bottom = 4 -padding.left = 0 - -[chat_panel.channel_select.menu] -padding = 4 -corner_radius = 6 -border = { color = "$border.0", width = 1 } -background = "$surface.0" -shadow = { offset = [0, 2], blur = 16, color = "$shadow.0" } - -[chat_panel.input_editor] -background = "$surface.1" -corner_radius = 6 -padding = { left = 8, right = 8, top = 7, bottom = 7 } -text = "$text.0" -placeholder_text = "$text.2" -selection = "$selection.host" -border = { width = 1, color = "$border.0" } - -[chat_panel.sign_in_prompt] -extends = "$text.0" -underline = true - -[chat_panel.hovered_sign_in_prompt] -extends = "$chat_panel.sign_in_prompt" -color = "$text.1.color" - -[contacts_panel] -extends = "$panel" -host_row_height = 28 -host_avatar = { corner_radius = 10, width = 18 } -host_username = { extends = "$text.0", padding.left = 8 } -tree_branch_width = 1 -tree_branch_color = "$surface.2" - -[contacts_panel.project] -height = 24 -padding = { left = 8 } -guest_avatar = { corner_radius = 8, width = 14 } -guest_avatar_spacing = 4 - -[contacts_panel.project.name] -extends = "$text.1" -margin = { right = 6 } - -[contacts_panel.unshared_project] -extends = "$contacts_panel.project" - -[contacts_panel.hovered_unshared_project] -extends = "$contacts_panel.unshared_project" -background = "$state.hover" -corner_radius = 6 - -[contacts_panel.shared_project] -extends = "$contacts_panel.project" -name.color = "$text.0.color" - -[contacts_panel.hovered_shared_project] -extends = "$contacts_panel.shared_project" -background = "$state.hover" -corner_radius = 6 - -[project_panel] -extends = "$panel" -padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2 - -[project_panel.entry] -text = "$text.1" -height = 22 -icon_color = "$text.3.color" -icon_size = 8 -icon_spacing = 8 - -[project_panel.hovered_entry] -extends = "$project_panel.entry" -background = "$state.hover" - -[project_panel.selected_entry] -extends = "$project_panel.entry" -text = { extends = "$text.0" } - -[project_panel.hovered_selected_entry] -extends = "$project_panel.hovered_entry" -text = { extends = "$text.0" } - -[selector] -background = "$surface.0" -padding = 8 -margin = { top = 52, bottom = 52 } -corner_radius = 6 -shadow = { offset = [0, 2], blur = 16, color = "$shadow.0" } -border = { width = 1, color = "$border.0" } - -[selector.input_editor] -background = "$surface.1" -corner_radius = 6 -padding = { left = 16, right = 16, top = 7, bottom = 7 } -text = "$text.0" -placeholder_text = "$text.2" -selection = "$selection.host" -border = { width = 1, color = "$border.0" } - -[selector.empty] -text = "$text.2" -padding = { left = 16, right = 16, top = 8, bottom = 4 } - -[selector.item] -text = "$text.1" -highlight_text = { extends = "$text.base", color = "$editor.syntax.keyword.color", weight = "$editor.syntax.keyword.weight" } -padding = { left = 16, right = 16, top = 4, bottom = 4 } -corner_radius = 6 - -[selector.active_item] -extends = "$selector.item" -background = "$state.hover" -text = "$text.0" - -[editor] -text_color = "$text.1.color" -background = "$surface.1" -gutter_background = "$surface.1" -gutter_padding_factor = 2.5 -active_line_background = "$state.active_line" -highlighted_line_background = "$state.highlighted_line" -rename_fade = 0.6 -unnecessary_code_fade = 0.5 -document_highlight_read_background = "#99999920" -document_highlight_write_background = "#99999916" -diff_background_deleted = "$state.deleted_line" -diff_background_inserted = "$state.inserted_line" -line_number = "$text.2.color" -line_number_active = "$text.0.color" -selection = "$selection.host" -guest_selections = "$selection.guests" -error_color = "$status.bad" -code_actions_indicator = "$text.3.color" - -[editor.diagnostic_path_header] -background = "$state.active_line" -filename = { extends = "$text.0", size = 14 } -path = { extends = "$text.2", size = 14, margin.left = 12 } -text_scale_factor = 0.857 - -[editor.diagnostic_header] -background = "$editor.background" -border = { width = 1, top = true, bottom = true, color = "$border.1" } -code = { extends = "$text.2", size = 14, margin.left = 10 } -icon_width_factor = 1.5 -text_scale_factor = 0.857 - -[editor.diagnostic_header.message] -text = { extends = "$text.1", size = 14 } -highlight_text = { extends = "$text.0", size = 14, weight = "bold" } - -[editor.error_diagnostic] -header.border = { width = 1, top = true, color = "$border.0" } -text_scale_factor = 0.857 - -[editor.error_diagnostic.message] -text = { extends = "$text.1", size = 14, color = "$status.bad" } -highlight_text = { extends = "$text.1", size = 14, color = "$status.bad", weight = "bold" } - -[editor.warning_diagnostic] -extends = "$editor.error_diagnostic" -message.text.color = "$status.warn" -message.highlight_text.color = "$status.warn" - -[editor.information_diagnostic] -extends = "$editor.error_diagnostic" -message.text.color = "$status.info" -message.highlight_text.color = "$status.info" - -[editor.hint_diagnostic] -extends = "$editor.error_diagnostic" -message.text.color = "$status.info" -message.highlight_text.color = "$status.info" - -[editor.invalid_error_diagnostic] -extends = "$editor.error_diagnostic" -message.text.color = "$text.3.color" -message.highlight_text.color = "$text.3.color" - -[editor.invalid_warning_diagnostic] -extends = "$editor.warning_diagnostic" -message.text.color = "$text.3.color" -message.highlight_text.color = "$text.3.color" - -[editor.invalid_information_diagnostic] -extends = "$editor.information_diagnostic" -message.text.color = "$text.3.color" -message.highlight_text.color = "$text.3.color" - -[editor.invalid_hint_diagnostic] -extends = "$editor.hint_diagnostic" -message.text.color = "$text.3.color" -message.highlight_text.color = "$text.3.color" - -[editor.autocomplete] -background = "$surface.2" -border = { width = 2, color = "$border.1" } -corner_radius = 6 -padding = 6 -match_highlight = { color = "$editor.syntax.keyword.color", weight = "$editor.syntax.keyword.weight" } -margin.left = -14 - -[editor.autocomplete.item] -padding = { left = 6, right = 6, top = 2, bottom = 2 } -corner_radius = 6 - -[editor.autocomplete.selected_item] -extends = "$editor.autocomplete.item" -background = "$state.selected" - -[editor.autocomplete.hovered_item] -extends = "$editor.autocomplete.item" -background = "$state.hover" - -[project_diagnostics] -background = "$surface.1" -empty_message = { extends = "$text.0", size = 18 } -status_bar_item = { extends = "$text.2", margin.right = 10 } -tab_icon_width = 13 -tab_icon_spacing = 4 -tab_summary_spacing = 10 - -[search] -match_background = "$state.highlighted_line" -results_status = { extends = "$text.0", size = 18 } -tab_icon_width = 14 -tab_icon_spacing = 4 - -[search.option_button] -extends = "$text.1" -padding = { left = 6, right = 6, top = 1, bottom = 1 } -corner_radius = 6 -background = "$surface.1" -border = { width = 1, color = "$border.0" } -margin.left = 1 -margin.right = 1 - -[search.option_button_group] -padding = { left = 2, right = 2 } - -[search.active_option_button] -extends = "$search.option_button" -background = "$surface.2" - -[search.hovered_option_button] -extends = "$search.option_button" -background = "$surface.2" - -[search.active_hovered_option_button] -extends = "$search.option_button" -background = "$surface.2" - -[search.match_index] -extends = "$text.2" -padding = 6 - -[search.editor] -min_width = 200 -max_width = 500 -background = "$surface.0" -corner_radius = 6 -padding = { left = 14, right = 14, top = 3, bottom = 3 } -margin = { right = 5 } -text = "$text.0" -placeholder_text = "$text.2" -selection = "$selection.host" -border = { width = 1, color = "$border.0" } - -[search.invalid_editor] -extends = "$search.editor" -border = { width = 1, color = "$status.bad" } diff --git a/crates/zed/assets/themes/black.toml b/crates/zed/assets/themes/black.toml deleted file mode 100644 index 34de16627ec3b5c0e9313f1d784881b322ade52e..0000000000000000000000000000000000000000 --- a/crates/zed/assets/themes/black.toml +++ /dev/null @@ -1,67 +0,0 @@ -extends = "_base" - -[surface] -0 = "#222222" -1 = "#0f0b0c" -2 = "#131415" - -[border] -0 = "#000000B2" -1 = "#FFFFFF20" - -[text] -0 = { extends = "$text.base", color = "#ffffff" } -1 = { extends = "$text.base", color = "#b3b3b3" } -2 = { extends = "$text.base", color = "#7b7d80" } -3 = { extends = "$text.base", color = "#66686A" } - -[shadow] -0 = "#00000052" - -[selection] -host = { selection = "#3B57BC55", cursor = "$text.0.color" } -guests = [ - { selection = "#FDF35133", cursor = "#FDF351" }, - { selection = "#4EACAD33", cursor = "#4EACAD" }, - { selection = "#D0453B33", cursor = "#D0453B" }, - { selection = "#3B874B33", cursor = "#3B874B" }, - { selection = "#BD7CB433", cursor = "#BD7CB4" }, - { selection = "#EE823133", cursor = "#EE8231" }, - { selection = "#5A2B9233", cursor = "#5A2B92" }, -] - -[status] -good = "#4fac63" -info = "#3c5dd4" -warn = "#faca50" -bad = "#b7372e" - -[state] -active_line = "#161313" -highlighted_line = "#faca5033" -deleted_line = "#dd000036" -inserted_line = "#00dd0036" -hover = "#00000033" -selected = "#00000088" - -[editor.syntax] -keyword = { color = "#0086c0", weight = "bold" } -function = "#dcdcaa" -string = "#cb8f77" -type = "#4ec9b0" -number = "#b5cea8" -comment = "#6a9955" -property = "#4e94ce" -variant = "#4fc1ff" -constant = "#9cdcfe" -title = { color = "#9cdcfe", weight = "bold" } -emphasis = "#4ec9b0" -"emphasis.strong" = { color = "#4ec9b0", weight = "bold" } -link_uri = { color = "#6a9955", underline = true } -link_text = { color = "#cb8f77", italic = true } -list_marker = "#4e94ce" - -[workspace.disconnected_overlay] -extends = "$text.base" -color = "#ffffff" -background = "#000000aa" diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json new file mode 100644 index 0000000000000000000000000000000000000000..65bf78b140ff3c94c298982cf2b3a6f6b8210609 --- /dev/null +++ b/crates/zed/assets/themes/dark.json @@ -0,0 +1,1245 @@ +{ + "selector": { + "background": "#e6e6e6", + "corner_radius": 6, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 4 + }, + "corner_radius": 6, + "text": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#2db4f3", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 4 + }, + "corner_radius": 6, + "text": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#2db4f3", + "weight": "bold", + "size": 14 + }, + "background": "#e6e6e6" + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 8 + } + }, + "input_editor": { + "background": "#cccccc", + "corner_radius": 6, + "placeholder_text": { + "family": "Zed Sans", + "color": "#bfbfbf", + "size": 14 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "margin": { + "bottom": 52, + "top": 52 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#e6e6e6", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 34, + "icon_close": "#808080", + "icon_close_active": "#0d0d0d", + "icon_conflict": "#f8c570", + "icon_dirty": "#6099f7", + "icon_width": 8, + "spacing": 10, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 12, + "right": 12 + } + }, + "active_tab": { + "height": 34, + "icon_close": "#808080", + "icon_close_active": "#0d0d0d", + "icon_conflict": "#f8c570", + "icon_dirty": "#6099f7", + "icon_width": 8, + "spacing": 10, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 12, + "right": 12 + }, + "background": "#cccccc" + }, + "left_sidebar": { + "width": 30, + "border": { + "color": "#d9d9d9", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#808080", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#4d4d4d", + "icon_size": 18 + }, + "resize_handle": { + "background": "#d9d9d9", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#808080", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#4d4d4d", + "icon_size": 18 + }, + "resize_handle": { + "background": "#d9d9d9", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#d9d9d9", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "share_icon_color": "#808080", + "share_icon_active_color": "#0d0d0d", + "title": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#595959", + "size": 13, + "underline": true, + "padding": { + "right": 8 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Mono", + "color": "#000000", + "size": 16, + "underline": true, + "padding": { + "right": 8 + } + }, + "offline_icon": { + "color": "#999999", + "width": 16, + "padding": { + "right": 4 + } + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 13 + } + }, + "toolbar": { + "height": 34, + "background": "#cccccc", + "border": { + "color": "#d9d9d9", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#ffffff", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#595959", + "background": "#cccccc", + "active_line_background": "#000000", + "code_actions_indicator": "#808080", + "diff_background_deleted": "#f78c8c", + "diff_background_inserted": "#22c55e", + "document_highlight_read_background": "#e6e6e6", + "document_highlight_write_background": "#e6e6e6", + "error_color": "#f78c8c", + "gutter_background": "#cccccc", + "gutter_padding_factor": 2.5, + "highlighted_line_background": "#000000", + "line_number": "#000000", + "line_number_active": "#000000", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "guest_selections": [ + { + "cursor": "#777af4", + "selection": "#777af4" + }, + { + "cursor": "#23d464", + "selection": "#23d464" + }, + { + "cursor": "#f98a3d", + "selection": "#f98a3d" + }, + { + "cursor": "#b671f8", + "selection": "#b671f8" + }, + { + "cursor": "#16ddc7", + "selection": "#16ddc7" + }, + { + "cursor": "#f58ac0", + "selection": "#f58ac0" + }, + { + "cursor": "#f6bc09", + "selection": "#f6bc09" + } + ], + "autocomplete": { + "background": "#bfbfbf", + "corner_radius": 6, + "padding": 6, + "border": { + "color": "#b3b3b3", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#bfbfbf" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "color": "#59c3f5", + "weight": "normal" + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#bfbfbf" + } + }, + "diagnostic_header": { + "background": "#e6e6e6", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#b3b3b3", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#262626", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#000000", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#262626", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#f78c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#f78c8c", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#f8c570", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#f8c570", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": {} + }, + "project_diagnostics": { + "background": "#cccccc", + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "project_panel": { + "padding": { + "top": 6 + }, + "entry": { + "height": 22, + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + } + }, + "hovered_entry": { + "height": 22, + "background": "#cccccc", + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#cccccc", + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#262626", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#cccccc", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#cccccc", + "corner_radius": 6 + }, + "menu": { + "background": "#e6e6e6", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#595959", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#262626", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#262626", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#8c8c8c", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#cccccc", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#bfbfbf", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#262626", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#262626", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#000000", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#000000", + "corner_radius": 6 + } + }, + "search": { + "match_background": "#000000", + "tab_icon_spacing": 4, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "editor": { + "background": "#e6e6e6", + "corner_radius": 6, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#bfbfbf", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "right": 5 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 14, + "right": 14 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "invalid_editor": { + "background": "#e6e6e6", + "corner_radius": 6, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#bfbfbf", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#ffffff", + "width": 1 + }, + "margin": { + "right": 5 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 14, + "right": 14 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#cccccc", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "option_button_group": { + "padding": { + "left": 2, + "right": 2 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#262626", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#262626", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/crates/zed/assets/themes/dark.toml b/crates/zed/assets/themes/dark.toml deleted file mode 100644 index fa673ac446426fed977dcf34abaa5361754e4db0..0000000000000000000000000000000000000000 --- a/crates/zed/assets/themes/dark.toml +++ /dev/null @@ -1,67 +0,0 @@ -extends = "_base" - -[surface] -0 = "#283340" -1 = "#1C2733" -2 = "#1C2733" - -[border] -0 = "#1B222B" -1 = "#FFFFFF20" - -[text] -0 = { extends = "$text.base", color = "#FFFFFF" } -1 = { extends = "$text.base", color = "#CDD1E2" } -2 = { extends = "$text.base", color = "#9BA8BE" } -3 = { extends = "$text.base", color = "#6E7483" } - -[shadow] -0 = "#00000052" - -[selection] -host = { selection = "#3B57BC55", cursor = "$text.0.color" } -guests = [ - { selection = "#FDF35133", cursor = "#FDF351" }, - { selection = "#4EACAD33", cursor = "#4EACAD" }, - { selection = "#D0453B33", cursor = "#D0453B" }, - { selection = "#3B874B33", cursor = "#3B874B" }, - { selection = "#BD7CB433", cursor = "#BD7CB4" }, - { selection = "#EE823133", cursor = "#EE8231" }, - { selection = "#5A2B9233", cursor = "#5A2B92" }, -] - -[status] -good = "#4fac63" -info = "#3c5dd4" -warn = "#faca50" -bad = "#b7372e" - -[state] -active_line = "#00000022" -highlighted_line = "#faca5033" -deleted_line = "#dd000036" -inserted_line = "#00dd0036" -hover = "#00000033" -selected = "#00000088" - -[editor.syntax] -keyword = { color = "#0086c0", weight = "bold" } -function = "#dcdcaa" -string = "#cb8f77" -type = "#4ec9b0" -number = "#b5cea8" -comment = "#6a9955" -property = "#4e94ce" -variant = "#4fc1ff" -constant = "#9cdcfe" -title = { color = "#9cdcfe", weight = "bold" } -emphasis = "#4ec9b0" -"emphasis.strong" = { color = "#4ec9b0", weight = "bold" } -link_uri = { color = "#6a9955", underline = true } -link_text = { color = "#cb8f77", italic = true } -list_marker = "#4e94ce" - -[workspace.disconnected_overlay] -extends = "$text.base" -color = "#ffffff" -background = "#000000aa" diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json new file mode 100644 index 0000000000000000000000000000000000000000..65bf78b140ff3c94c298982cf2b3a6f6b8210609 --- /dev/null +++ b/crates/zed/assets/themes/light.json @@ -0,0 +1,1245 @@ +{ + "selector": { + "background": "#e6e6e6", + "corner_radius": 6, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 4 + }, + "corner_radius": 6, + "text": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#2db4f3", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 4 + }, + "corner_radius": 6, + "text": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#2db4f3", + "weight": "bold", + "size": 14 + }, + "background": "#e6e6e6" + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 16, + "right": 16, + "top": 8 + } + }, + "input_editor": { + "background": "#cccccc", + "corner_radius": 6, + "placeholder_text": { + "family": "Zed Sans", + "color": "#bfbfbf", + "size": 14 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "margin": { + "bottom": 52, + "top": 52 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#e6e6e6", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 34, + "icon_close": "#808080", + "icon_close_active": "#0d0d0d", + "icon_conflict": "#f8c570", + "icon_dirty": "#6099f7", + "icon_width": 8, + "spacing": 10, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 12, + "right": 12 + } + }, + "active_tab": { + "height": 34, + "icon_close": "#808080", + "icon_close_active": "#0d0d0d", + "icon_conflict": "#f8c570", + "icon_dirty": "#6099f7", + "icon_width": 8, + "spacing": 10, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 12, + "right": 12 + }, + "background": "#cccccc" + }, + "left_sidebar": { + "width": 30, + "border": { + "color": "#d9d9d9", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#808080", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#4d4d4d", + "icon_size": 18 + }, + "resize_handle": { + "background": "#d9d9d9", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "border": { + "color": "#d9d9d9", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#808080", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#4d4d4d", + "icon_size": 18 + }, + "resize_handle": { + "background": "#d9d9d9", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#d9d9d9", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "share_icon_color": "#808080", + "share_icon_active_color": "#0d0d0d", + "title": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#d9d9d9", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#595959", + "size": 13, + "underline": true, + "padding": { + "right": 8 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Mono", + "color": "#000000", + "size": 16, + "underline": true, + "padding": { + "right": 8 + } + }, + "offline_icon": { + "color": "#999999", + "width": 16, + "padding": { + "right": 4 + } + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 13 + } + }, + "toolbar": { + "height": 34, + "background": "#cccccc", + "border": { + "color": "#d9d9d9", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#ffffff", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#595959", + "background": "#cccccc", + "active_line_background": "#000000", + "code_actions_indicator": "#808080", + "diff_background_deleted": "#f78c8c", + "diff_background_inserted": "#22c55e", + "document_highlight_read_background": "#e6e6e6", + "document_highlight_write_background": "#e6e6e6", + "error_color": "#f78c8c", + "gutter_background": "#cccccc", + "gutter_padding_factor": 2.5, + "highlighted_line_background": "#000000", + "line_number": "#000000", + "line_number_active": "#000000", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "guest_selections": [ + { + "cursor": "#777af4", + "selection": "#777af4" + }, + { + "cursor": "#23d464", + "selection": "#23d464" + }, + { + "cursor": "#f98a3d", + "selection": "#f98a3d" + }, + { + "cursor": "#b671f8", + "selection": "#b671f8" + }, + { + "cursor": "#16ddc7", + "selection": "#16ddc7" + }, + { + "cursor": "#f58ac0", + "selection": "#f58ac0" + }, + { + "cursor": "#f6bc09", + "selection": "#f6bc09" + } + ], + "autocomplete": { + "background": "#bfbfbf", + "corner_radius": 6, + "padding": 6, + "border": { + "color": "#b3b3b3", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#bfbfbf" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "color": "#59c3f5", + "weight": "normal" + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#bfbfbf" + } + }, + "diagnostic_header": { + "background": "#e6e6e6", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#b3b3b3", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#262626", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#000000", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#262626", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#f78c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#f78c8c", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#f8c570", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#f8c570", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#6099f7", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#d9d9d9", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": {} + }, + "project_diagnostics": { + "background": "#cccccc", + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "project_panel": { + "padding": { + "top": 6 + }, + "entry": { + "height": 22, + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + } + }, + "hovered_entry": { + "height": 22, + "background": "#cccccc", + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#595959", + "size": 16 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#cccccc", + "icon_color": "#999999", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#262626", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#cccccc", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#262626", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#cccccc", + "corner_radius": 6 + }, + "menu": { + "background": "#e6e6e6", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#595959", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#262626", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#595959", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#262626", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8c8c8c", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#8c8c8c", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#cccccc", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#bfbfbf", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#262626", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#262626", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#000000", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#000000", + "corner_radius": 6 + } + }, + "search": { + "match_background": "#000000", + "tab_icon_spacing": 4, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "editor": { + "background": "#e6e6e6", + "corner_radius": 6, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#bfbfbf", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "right": 5 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 14, + "right": 14 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#bfbfbf", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "invalid_editor": { + "background": "#e6e6e6", + "corner_radius": 6, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#bfbfbf", + "size": 16 + }, + "selection": { + "cursor": "#4287f6", + "selection": "#4287f6" + }, + "text": { + "family": "Zed Mono", + "color": "#262626", + "size": 16 + }, + "border": { + "color": "#ffffff", + "width": 1 + }, + "margin": { + "right": 5 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 14, + "right": 14 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#8c8c8c", + "size": 16, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#595959", + "size": 16, + "background": "#cccccc", + "corner_radius": 6, + "border": { + "color": "#d9d9d9", + "width": 1 + }, + "margin": { + "left": 1, + "right": 1 + }, + "padding": { + "bottom": 1, + "left": 6, + "right": 6, + "top": 1 + } + }, + "option_button_group": { + "padding": { + "left": 2, + "right": 2 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#262626", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#262626", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/crates/zed/assets/themes/light.toml b/crates/zed/assets/themes/light.toml deleted file mode 100644 index 2884515e09f41fc1ade19d886604e6af5ff2a1ae..0000000000000000000000000000000000000000 --- a/crates/zed/assets/themes/light.toml +++ /dev/null @@ -1,67 +0,0 @@ -extends = "_base" - -[surface] -0 = "#EAEAEB" -1 = "#FAFAFA" -2 = "#FFFFFF" - -[border] -0 = "#DDDDDC" -1 = "#0000000F" - -[text] -0 = { extends = "$text.base", color = "#000000" } -1 = { extends = "$text.base", color = "#29292B" } -2 = { extends = "$text.base", color = "#7E7E83" } -3 = { extends = "$text.base", color = "#939393" } - -[shadow] -0 = "#0000000D" - -[selection] -host = { selection = "#3B57BC55", cursor = "$text.0.color" } -guests = [ - { selection = "#D0453B33", cursor = "#D0453B" }, - { selection = "#3B874B33", cursor = "#3B874B" }, - { selection = "#BD7CB433", cursor = "#BD7CB4" }, - { selection = "#EE823133", cursor = "#EE8231" }, - { selection = "#5A2B9233", cursor = "#5A2B92" }, - { selection = "#FDF35133", cursor = "#FDF351" }, - { selection = "#4EACAD33", cursor = "#4EACAD" }, -] - -[status] -good = "#4fac63" -info = "#3c5dd4" -warn = "#faca50" -bad = "#b7372e" - -[state] -active_line = "#00000008" -highlighted_line = "#faca5033" -deleted_line = "#dd000036" -inserted_line = "#00dd0036" -hover = "#0000000D" -selected = "#0000001c" - -[editor.syntax] -keyword = { color = "#0000fa", weight = "bold" } -function = "#795e26" -string = "#a82121" -type = "#267f29" -number = "#b5cea8" -comment = "#6a9955" -property = "#4e94ce" -variant = "#4fc1ff" -constant = "#5a9ccc" -title = { color = "#5a9ccc", weight = "bold" } -emphasis = "#267f29" -"emphasis.strong" = { color = "#267f29", weight = "bold" } -link_uri = { color = "#6a9955", underline = true } -link_text = { color = "#a82121", italic = true } -list_marker = "#4e94ce" - -[workspace.disconnected_overlay] -extends = "$text.base" -color = "#ffffff" -background = "#000000cc" diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index aec0bc533e4a1842789b813c4fc060eaa334e165..dd4268fd76902294345138e4c9d340378c894434 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -988,7 +988,8 @@ mod tests { lazy_static::lazy_static! { static ref DEFAULT_THEME: parking_lot::Mutex>> = Default::default(); static ref FONTS: Vec>> = vec![ - Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap().to_vec().into() + Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap().to_vec().into(), + Assets.load("fonts/zed-mono/zed-mono-extended.ttf").unwrap().to_vec().into(), ]; } diff --git a/styles/buildThemes.ts b/styles/buildThemes.ts index ced82e98664980b3d1af9f50d8f4f8f498f59d49..d67860cee66a0ec7abd7d37da8b10f0a6c930488 100644 --- a/styles/buildThemes.ts +++ b/styles/buildThemes.ts @@ -7,11 +7,11 @@ import decamelizeTree from "./utils/decamelizeTree"; const themes = [dark, light]; for (let theme of themes) { - let styleTree = decamelizeTree(app(theme)); - let styleTreeJSON = JSON.stringify(styleTree, null, 2); - let outPath = path.resolve( - `${__dirname}/../crates/zed/assets/themes/${theme.name}.json` - ); - fs.writeFileSync(outPath, styleTreeJSON); - console.log(`Generated ${outPath}`); + let styleTree = decamelizeTree(app(theme)); + let styleTreeJSON = JSON.stringify(styleTree, null, 2); + let outPath = path.resolve( + `${__dirname}/../crates/zed/assets/themes/${theme.name}.json` + ); + fs.writeFileSync(outPath, styleTreeJSON); + console.log(`Generated ${outPath}`); } diff --git a/styles/styleTree/app.ts b/styles/styleTree/app.ts index c7edfdc2701f06e6cb1b41beb779ad6bc0aca75b..d26ada4fc9bc6ebab7c63255245ff003dfae0640 100644 --- a/styles/styleTree/app.ts +++ b/styles/styleTree/app.ts @@ -1,6 +1,7 @@ import Theme from "../themes/theme"; import chatPanel from "./chatPanel"; import { backgroundColor, borderColor, text } from "./components"; +import contactsPanel from "./contactsPanel"; import editor from "./editor"; import projectPanel from "./projectPanel"; import search from "./search"; @@ -8,83 +9,38 @@ import selectorModal from "./selectorModal"; import workspace from "./workspace"; export const panel = { - padding: { top: 12, left: 12, bottom: 12, right: 12 }, + padding: { top: 12, left: 12, bottom: 12, right: 12 }, }; export default function app(theme: Theme): Object { - return { - selector: selectorModal(theme), - workspace: workspace(theme), - editor: editor(theme), - projectDiagnostics: { - background: backgroundColor(theme, 300), - tabIconSpacing: 4, - tabIconWidth: 13, - tabSummarySpacing: 10, - emptyMessage: { - ...text(theme, "sans", "primary", { size: "lg" }), - }, - statusBarItem: { - ...text(theme, "sans", "muted"), - margin: { - right: 10, + return { + selector: selectorModal(theme), + workspace: workspace(theme), + editor: editor(theme), + projectDiagnostics: { + background: backgroundColor(theme, 300), + tabIconSpacing: 4, + tabIconWidth: 13, + tabSummarySpacing: 10, + emptyMessage: { + ...text(theme, "sans", "primary", { size: "lg" }), + }, + statusBarItem: { + ...text(theme, "sans", "muted"), + margin: { + right: 10, + }, + }, }, - }, - }, - projectPanel: projectPanel(theme), - chatPanel: chatPanel(theme), - contactsPanel: { - ...panel, - hostRowHeight: 28, - treeBranchColor: borderColor(theme, "muted"), - treeBranchWidth: 1, - hostAvatar: { - cornerRadius: 10, - width: 18, - }, - hostUsername: { - ...text(theme, "mono", "muted"), - padding: { - left: 8, - }, - }, - hoveredSharedProject: { - extends: "$contacts_panel.sharedProject", - background: theme.editor.line.active.value, - cornerRadius: 6, - }, - hoveredUnsharedProject: { - extends: "$contacts_panel.unsharedProject", - background: theme.editor.line.active.value, - cornerRadius: 6, - }, - project: { - guestAvatarSpacing: 4, - height: 24, - guestAvatar: { - cornerRadius: 8, - width: 14, - }, - name: { - extends: text(theme, "mono", "secondary"), - margin: { - right: 6, - }, - }, - padding: { - left: 8, - }, - }, - sharedProject: { - extends: "$contactsPanel.project", - name: { - color: text(theme, "mono", "primary"), - }, - }, - unsharedProject: { - extends: "$contactsPanel.project", - }, - }, - search: search(theme), - }; + projectPanel: projectPanel(theme), + chatPanel: chatPanel(theme), + contactsPanel: contactsPanel(theme), + search: search(theme), + breadcrumbs: { + ...text(theme, "sans", "primary"), + padding: { + left: 6, + }, + } + }; } diff --git a/styles/styleTree/components.ts b/styles/styleTree/components.ts index 55a64cb1ecb4ec8f60878d9e795f671a9a5cfede..205fd9b26200510d7adeb4f226ed893e8a17bbaa 100644 --- a/styles/styleTree/components.ts +++ b/styles/styleTree/components.ts @@ -1,25 +1,25 @@ import chroma from "chroma-js"; -import Theme, { BackgroundColor, Weight } from "../themes/theme"; -import core from "../tokens/core"; +import Theme, { BackgroundColor } from "../themes/theme"; +import { fontFamilies, fontSizes, FontWeight } from "../tokens"; import { Color } from "../utils/color"; export type TextColor = keyof Theme["textColor"]; export function text( theme: Theme, - fontFamily: keyof typeof core.fontFamily, + fontFamily: keyof typeof fontFamilies, color: TextColor, properties?: { - size?: keyof typeof core["fontSize"]; - weight?: Weight; + size?: keyof typeof fontSizes; + weight?: FontWeight; underline?: boolean; } ) { const sizeKey = properties?.size || fontFamily === "sans" ? "sm" : "md"; - const size = core.fontSize[sizeKey].value; + const size = fontSizes[sizeKey].value; return { - family: core.fontFamily[fontFamily], + family: fontFamilies[fontFamily].value, color: theme.textColor[color].value, ...properties, size, diff --git a/styles/styleTree/contactsPanel.ts b/styles/styleTree/contactsPanel.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b88a35f13692712cd61c89d4af75476d7bb49c6 --- /dev/null +++ b/styles/styleTree/contactsPanel.ts @@ -0,0 +1,61 @@ +import Theme from "../themes/theme"; +import { panel } from "./app"; +import { borderColor, text } from "./components"; + +export default function(theme: Theme) { + const project = { + guestAvatarSpacing: 4, + height: 24, + guestAvatar: { + cornerRadius: 8, + width: 14, + }, + name: { + ...text(theme, "mono", "secondary"), + margin: { + right: 6, + }, + }, + padding: { + left: 8, + }, + }; + + const sharedProject = { + ...project, + name: { + ...project.name, + ...text(theme, "mono", "primary"), + }, + }; + + return { + ...panel, + hostRowHeight: 28, + treeBranchColor: borderColor(theme, "muted"), + treeBranchWidth: 1, + hostAvatar: { + cornerRadius: 10, + width: 18, + }, + hostUsername: { + ...text(theme, "mono", "muted"), + padding: { + left: 8, + }, + }, + project, + sharedProject, + hoveredSharedProject: { + ...sharedProject, + background: theme.editor.line.active.value, + cornerRadius: 6, + }, + unsharedProject: project, + hoveredUnsharedProject: { + ...project, + background: theme.editor.line.active.value, + cornerRadius: 6, + }, + } +} \ No newline at end of file diff --git a/styles/styleTree/editor.ts b/styles/styleTree/editor.ts index 5d800881e2750942c2b7d6f1113df203aff97fb3..ebc53b405875dab197a3c95d5373732050e9a7a0 100644 --- a/styles/styleTree/editor.ts +++ b/styles/styleTree/editor.ts @@ -1,131 +1,134 @@ import Theme from "../themes/theme"; import { - backgroundColor, - border, - iconColor, - player, - text, - TextColor + backgroundColor, + border, + iconColor, + player, + text, + TextColor, } from "./components"; export default function editor(theme: Theme) { - const autocompleteItem = { - cornerRadius: 6, - padding: { - bottom: 2, - left: 6, - right: 6, - top: 2, - }, - }; - - function diagnostic(theme: Theme, color: TextColor) { - return { - textScaleFactor: 0.857, - header: { - border: border(theme, "primary", { - top: true, - }), - }, - message: { - text: text(theme, "sans", color, { size: "sm" }), - highlightText: text(theme, "sans", color, { - size: "sm", - weight: "bold", - }), - }, + const autocompleteItem = { + cornerRadius: 6, + padding: { + bottom: 2, + left: 6, + right: 6, + top: 2, + }, }; - } - return { - textColor: theme.textColor.secondary.value, - background: backgroundColor(theme, 300), - activeLineBackground: theme.editor.line.active.value, - codeActionsIndicator: iconColor(theme, "secondary"), - diffBackgroundDeleted: backgroundColor(theme, "error"), - diffBackgroundInserted: backgroundColor(theme, "ok"), - documentHighlightReadBackground: theme.editor.highlight.occurrence.value, - documentHighlightWriteBackground: theme.editor.highlight.occurrence.value, - errorColor: theme.textColor.error, - gutterBackground: backgroundColor(theme, 300), - gutterPaddingFactor: 2.5, - highlightedLineBackground: theme.editor.line.highlighted.value, - lineNumber: theme.editor.gutter.primary.value, - lineNumberActive: theme.editor.gutter.active, - renameFade: 0.6, - unnecessaryCodeFade: 0.5, - selection: player(theme, 1).selection, - guestSelections: [ - player(theme, 2).selection, - player(theme, 3).selection, - player(theme, 4).selection, - player(theme, 5).selection, - player(theme, 6).selection, - player(theme, 7).selection, - player(theme, 8).selection, - ], - autocomplete: { - background: backgroundColor(theme, 100), - cornerRadius: 6, - padding: 6, - border: border(theme, "secondary"), - item: autocompleteItem, - hoveredItem: { - ...autocompleteItem, - background: backgroundColor(theme, 100, "hovered"), - }, - margin: { - left: -14, - }, - matchHighlight: { - color: theme.syntax.keyword.color.value, - weight: theme.syntax.keyword.weight.value, - }, - selectedItem: { - ...autocompleteItem, - background: backgroundColor(theme, 100, "active"), - }, - }, - diagnosticHeader: { - background: theme.editor.background.value, - iconWidthFactor: 1.5, - textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. - border: border(theme, "secondary", { - bottom: true, - top: true, - }), - code: { - ...text(theme, "mono", "muted", { size: "sm" }), - margin: { - left: 10, + function diagnostic(theme: Theme, color: TextColor) { + return { + textScaleFactor: 0.857, + header: { + border: border(theme, "primary", { + top: true, + }), + }, + message: { + text: text(theme, "sans", color, { size: "sm" }), + highlightText: text(theme, "sans", color, { + size: "sm", + weight: "bold", + }), + }, + }; + } + + return { + textColor: theme.textColor.secondary.value, + background: backgroundColor(theme, 300), + activeLineBackground: theme.editor.line.active.value, + codeActionsIndicator: iconColor(theme, "secondary"), + diffBackgroundDeleted: backgroundColor(theme, "error"), + diffBackgroundInserted: backgroundColor(theme, "ok"), + documentHighlightReadBackground: theme.editor.highlight.occurrence.value, + documentHighlightWriteBackground: theme.editor.highlight.occurrence.value, + errorColor: theme.textColor.error.value, + gutterBackground: backgroundColor(theme, 300), + gutterPaddingFactor: 2.5, + highlightedLineBackground: theme.editor.line.highlighted.value, + lineNumber: theme.editor.gutter.primary.value, + lineNumberActive: theme.editor.gutter.active.value, + renameFade: 0.6, + unnecessaryCodeFade: 0.5, + selection: player(theme, 1).selection, + guestSelections: [ + player(theme, 2).selection, + player(theme, 3).selection, + player(theme, 4).selection, + player(theme, 5).selection, + player(theme, 6).selection, + player(theme, 7).selection, + player(theme, 8).selection, + ], + autocomplete: { + background: backgroundColor(theme, 100), + cornerRadius: 6, + padding: 6, + border: border(theme, "secondary"), + item: autocompleteItem, + hoveredItem: { + ...autocompleteItem, + background: backgroundColor(theme, 100, "hovered"), + }, + margin: { + left: -14, + }, + matchHighlight: { + color: theme.syntax.keyword.color.value, + weight: theme.syntax.keyword.weight.value, + }, + selectedItem: { + ...autocompleteItem, + background: backgroundColor(theme, 100, "active"), + }, + }, + diagnosticHeader: { + background: theme.editor.background.value, + iconWidthFactor: 1.5, + textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. + border: border(theme, "secondary", { + bottom: true, + top: true, + }), + code: { + ...text(theme, "mono", "muted", { size: "sm" }), + margin: { + left: 10, + }, + }, + message: { + highlightText: text(theme, "sans", "primary", { + size: "sm", + weight: "bold", + }), + text: text(theme, "sans", "secondary", { size: "sm" }), + }, }, - }, - message: { - highlightText: text(theme, "sans", "primary", { - size: "sm", - weight: "bold", - }), - text: text(theme, "sans", "secondary", { size: "sm" }), - }, - }, - diagnosticPathHeader: { - background: theme.editor.line.active, - textScaleFactor: 0.857, - filename: text(theme, "mono", "primary", { size: "sm" }), - path: { - ...text(theme, "mono", "muted", { size: "sm" }), - margin: { - left: 12, + diagnosticPathHeader: { + background: theme.editor.line.active.value, + textScaleFactor: 0.857, + filename: text(theme, "mono", "primary", { size: "sm" }), + path: { + ...text(theme, "mono", "muted", { size: "sm" }), + margin: { + left: 12, + }, + }, }, - }, - }, - errorDiagnostic: diagnostic(theme, "error"), - warningDiagnostic: diagnostic(theme, "warning"), - informationDiagnostic: diagnostic(theme, "info"), - hintDiagnostic: diagnostic(theme, "info"), - invalidErrorDiagnostic: diagnostic(theme, "muted"), - invalidHintDiagnostic: diagnostic(theme, "muted"), - invalidInformationDiagnostic: diagnostic(theme, "muted"), - invalidWarningDiagnostic: diagnostic(theme, "muted"), - }; + errorDiagnostic: diagnostic(theme, "error"), + warningDiagnostic: diagnostic(theme, "warning"), + informationDiagnostic: diagnostic(theme, "info"), + hintDiagnostic: diagnostic(theme, "info"), + invalidErrorDiagnostic: diagnostic(theme, "muted"), + invalidHintDiagnostic: diagnostic(theme, "muted"), + invalidInformationDiagnostic: diagnostic(theme, "muted"), + invalidWarningDiagnostic: diagnostic(theme, "muted"), + syntax: { + + } + }; } diff --git a/styles/styleTree/projectPanel.ts b/styles/styleTree/projectPanel.ts index 3b5fba8853da3799e69be735447e615341ef8391..cd6fb49b3ada1db47b3dd15637cb1a4a6c5ee516 100644 --- a/styles/styleTree/projectPanel.ts +++ b/styles/styleTree/projectPanel.ts @@ -24,7 +24,11 @@ export default function projectPanel(theme: Theme) { backgroundColor(theme, 300, "hovered") ), selectedEntry: entry(theme, "primary"), - hoveredSelectedEntry: entry(theme, "primary", "hovered"), + hoveredSelectedEntry: entry( + theme, + "primary", + backgroundColor(theme, 300, "hovered") + ), padding: { top: 6, }, diff --git a/styles/styleTree/search.ts b/styles/styleTree/search.ts index 7ba04cd688e01f5b3a4f47b35311195fde73fefb..42b639f57a39d355c8dbf461fb29e64ee71dec2f 100644 --- a/styles/styleTree/search.ts +++ b/styles/styleTree/search.ts @@ -19,8 +19,28 @@ export default function search(theme: Theme) { }, }; + const editor = { + background: backgroundColor(theme, 500), + cornerRadius: 6, + minWidth: 200, + maxWidth: 500, + placeholderText: text(theme, "mono", "placeholder"), + selection: player(theme, 1).selection, + text: text(theme, "mono", "primary"), + border: border(theme, "primary"), + margin: { + right: 5, + }, + padding: { + top: 3, + bottom: 3, + left: 14, + right: 14, + }, + }; + return { - matchBackground: theme.editor.highlight.match, + matchBackground: theme.editor.highlight.match.value, tabIconSpacing: 4, tabIconWidth: 14, activeHoveredOptionButton: { @@ -31,31 +51,13 @@ export default function search(theme: Theme) { ...optionButton, background: backgroundColor(theme, 100), }, - editor: { - background: backgroundColor(theme, 500), - cornerRadius: 6, - minWidth: 200, - maxWidth: 500, - placeholderText: text(theme, "mono", "placeholder"), - selection: player(theme, 1).selection, - text: text(theme, "mono", "primary"), - border: border(theme, "primary"), - margin: { - right: 5, - }, - padding: { - top: 3, - bottom: 3, - left: 14, - right: 14, - }, - }, + editor, hoveredOptionButton: { ...optionButton, background: backgroundColor(theme, 100), }, invalidEditor: { - extends: "$search.editor", + ...editor, border: border(theme, "error"), }, matchIndex: { diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index 148db089183e77274a81a122d6f02d920b640237..7e71eaad2a8e258e5aed2476af0b68fbf9c7ba4b 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -137,5 +137,10 @@ export default function workspace(theme: Theme) { ...text(theme, "mono", "secondary"), padding: { left: 6 }, }, + disconnectedOverlay: { + ...text(theme, "sans", "primary"), + color: "#ffffff", + background: "#000000aa", + }, }; } diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index 42f80cf4c670deda733f434c3cbab691239f5396..2cadf24601f47cc1172c4d9be753cc80c3a9f20c 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -1,249 +1,273 @@ -import core from "../tokens/core"; -import Theme, { NumberToken, Syntax } from "./theme"; - -const { color } = core; +import { colors, fontWeights, NumberToken } from "../tokens"; +import Theme, { Syntax } from "./theme"; const backgroundColor = { - 100: { - base: color.neutral[750], - hovered: color.neutral[750], - active: color.neutral[750], - focused: color.neutral[750], - }, - 300: { - base: color.neutral[800], - hovered: color.neutral[800], - active: color.neutral[800], - focused: color.neutral[800], - }, - 500: { - base: color.neutral[900], - hovered: color.neutral[900], - active: color.neutral[900], - focused: color.neutral[900], - }, - ok: { - base: color.green[600], - hovered: color.green[600], - active: color.green[600], - focused: color.green[600], - }, - error: { - base: color.red[400], - hovered: color.red[400], - active: color.red[400], - focused: color.red[400], - }, - warning: { - base: color.amber[300], - hovered: color.amber[300], - active: color.amber[300], - focused: color.amber[300], - }, - info: { - base: color.blue[500], - hovered: color.blue[500], - active: color.blue[500], - focused: color.blue[500], - }, + 100: { + base: colors.neutral[750], + hovered: colors.neutral[750], + active: colors.neutral[750], + focused: colors.neutral[750], + }, + 300: { + base: colors.neutral[800], + hovered: colors.neutral[800], + active: colors.neutral[800], + focused: colors.neutral[800], + }, + 500: { + base: colors.neutral[900], + hovered: colors.neutral[900], + active: colors.neutral[900], + focused: colors.neutral[900], + }, + ok: { + base: colors.green[600], + hovered: colors.green[600], + active: colors.green[600], + focused: colors.green[600], + }, + error: { + base: colors.red[400], + hovered: colors.red[400], + active: colors.red[400], + focused: colors.red[400], + }, + warning: { + base: colors.amber[300], + hovered: colors.amber[300], + active: colors.amber[300], + focused: colors.amber[300], + }, + info: { + base: colors.blue[500], + hovered: colors.blue[500], + active: colors.blue[500], + focused: colors.blue[500], + }, }; const borderColor = { - primary: color.neutral[850], - secondary: color.neutral[700], - muted: color.neutral[750], - focused: color.neutral[100], - active: color.neutral[500], - ok: color.neutral[1000], - error: color.neutral[1000], - warning: color.neutral[1000], - info: color.neutral[1000], + primary: colors.neutral[850], + secondary: colors.neutral[700], + muted: colors.neutral[750], + focused: colors.neutral[100], + active: colors.neutral[500], + ok: colors.neutral[1000], + error: colors.neutral[1000], + warning: colors.neutral[1000], + info: colors.neutral[1000], }; const textColor = { - primary: color.neutral[150], - secondary: color.neutral[350], - muted: color.neutral[550], - placeholder: color.neutral[750], - active: color.neutral[0], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: colors.neutral[150], + secondary: colors.neutral[350], + muted: colors.neutral[550], + placeholder: colors.neutral[750], + active: colors.neutral[0], + //TODO: (design) define feature and it's correct value + feature: colors.sky[500], + ok: colors.green[600], + error: colors.red[400], + warning: colors.amber[300], + info: colors.blue[500], }; const iconColor = { - primary: color.neutral[300], - secondary: color.neutral[500], - muted: color.neutral[600], - placeholder: color.neutral[700], - active: color.neutral[50], - //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + primary: colors.neutral[300], + secondary: colors.neutral[500], + muted: colors.neutral[600], + placeholder: colors.neutral[700], + active: colors.neutral[50], + //TODO: (design) define feature and it's correct value + feature: colors.sky[500], + ok: colors.green[600], + error: colors.red[400], + warning: colors.amber[300], + info: colors.blue[500], }; const player = { - 1: { - baseColor: color.blue[600], - cursorColor: color.blue[600], - selectionColor: color.blue[600], - borderColor: color.blue[600], - }, - 2: { - baseColor: color.indigo[500], - cursorColor: color.indigo[500], - selectionColor: color.indigo[500], - borderColor: color.indigo[500], - }, - 3: { - baseColor: color.green[500], - cursorColor: color.green[500], - selectionColor: color.green[500], - borderColor: color.green[500], - }, - 4: { - baseColor: color.orange[500], - cursorColor: color.orange[500], - selectionColor: color.orange[500], - borderColor: color.orange[500], - }, - 5: { - baseColor: color.purple[500], - cursorColor: color.purple[500], - selectionColor: color.purple[500], - borderColor: color.purple[500], - }, - 6: { - baseColor: color.teal[400], - cursorColor: color.teal[400], - selectionColor: color.teal[400], - borderColor: color.teal[400], - }, - 7: { - baseColor: color.pink[400], - cursorColor: color.pink[400], - selectionColor: color.pink[400], - borderColor: color.pink[400], - }, - 8: { - baseColor: color.yellow[400], - cursorColor: color.yellow[400], - selectionColor: color.yellow[400], - borderColor: color.yellow[400], - }, + 1: { + baseColor: colors.blue[600], + cursorColor: colors.blue[600], + selectionColor: colors.blue[600], + borderColor: colors.blue[600], + }, + 2: { + baseColor: colors.indigo[500], + cursorColor: colors.indigo[500], + selectionColor: colors.indigo[500], + borderColor: colors.indigo[500], + }, + 3: { + baseColor: colors.green[500], + cursorColor: colors.green[500], + selectionColor: colors.green[500], + borderColor: colors.green[500], + }, + 4: { + baseColor: colors.orange[500], + cursorColor: colors.orange[500], + selectionColor: colors.orange[500], + borderColor: colors.orange[500], + }, + 5: { + baseColor: colors.purple[500], + cursorColor: colors.purple[500], + selectionColor: colors.purple[500], + borderColor: colors.purple[500], + }, + 6: { + baseColor: colors.teal[400], + cursorColor: colors.teal[400], + selectionColor: colors.teal[400], + borderColor: colors.teal[400], + }, + 7: { + baseColor: colors.pink[400], + cursorColor: colors.pink[400], + selectionColor: colors.pink[400], + borderColor: colors.pink[400], + }, + 8: { + baseColor: colors.yellow[400], + cursorColor: colors.yellow[400], + selectionColor: colors.yellow[400], + borderColor: colors.yellow[400], + }, }; // TODO: Fixup const editor = { - background: backgroundColor[500].base, - indent_guide: borderColor.muted, - indent_guide_active: borderColor.secondary, - line: { - active: color.neutral[0], - highlighted: color.neutral[0], - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, - }, - highlight: { - selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: color.neutral[0], - matchingBracket: color.neutral[0], - match: color.neutral[0], - activeMatch: color.neutral[0], - related: color.neutral[0], - }, - gutter: { - primary: color.neutral[0], - active: color.neutral[0], - }, + background: backgroundColor[500].base, + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, + line: { + active: colors.neutral[0], + highlighted: colors.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, + }, + highlight: { + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: colors.neutral[0], + matchingBracket: colors.neutral[0], + match: colors.neutral[0], + activeMatch: colors.neutral[0], + related: colors.neutral[0], + }, + gutter: { + primary: colors.neutral[0], + active: colors.neutral[0], + }, }; const syntax: Syntax = { - primary: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - comment: { - color: color.lime[200], - weight: { value: "normal", type: "fontWeight" }, - }, - punctuation: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, - }, - constant: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - keyword: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - function: { - color: color.yellow[200], - weight: { value: "normal", type: "fontWeight" }, - }, - type: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - variant: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, - }, - property: { - color: color.sky[300], - weight: { value: "normal", type: "fontWeight" }, - }, - enum: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - operator: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, - }, - string: { - color: color.orange[300], - weight: { value: "normal", type: "fontWeight" }, - }, - number: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - boolean: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, - }, - predictive: { - color: textColor.muted, - weight: { value: "normal", type: "fontWeight" }, - }, + primary: { + color: textColor.primary, + weight: fontWeights.normal, + }, + comment: { + color: colors.lime[200], + weight: fontWeights.normal, + }, + punctuation: { + color: textColor.primary, + weight: fontWeights.normal, + }, + constant: { + color: colors.neutral[150], + weight: fontWeights.normal, + }, + keyword: { + color: colors.sky[400], + weight: fontWeights.normal, + }, + function: { + color: colors.yellow[200], + weight: fontWeights.normal, + }, + type: { + color: colors.teal[300], + weight: fontWeights.normal, + }, + variant: { + color: colors.teal[300], + weight: fontWeights.normal, + }, + property: { + color: colors.sky[300], + weight: fontWeights.normal, + }, + enum: { + color: colors.sky[400], + weight: fontWeights.normal, + }, + operator: { + color: colors.sky[400], + weight: fontWeights.normal, + }, + string: { + color: colors.orange[300], + weight: fontWeights.normal, + }, + number: { + color: colors.neutral[150], + weight: fontWeights.normal, + }, + boolean: { + color: colors.neutral[150], + weight: fontWeights.normal, + }, + predictive: { + color: textColor.muted, + weight: fontWeights.normal, + }, + title: { + color: colors.sky[500], + weight: fontWeights.bold, + }, + emphasis: { + color: textColor.active, + weight: fontWeights.normal, + }, + emphasisStrong: { + color: textColor.active, + weight: fontWeights.bold, + }, + linkUrl: { + color: colors.lime[500], + weight: fontWeights.normal, + // TODO: add underline + }, + linkText: { + color: colors.orange[500], + weight: fontWeights.normal, + // TODO: add italic + }, + listMarker: { + color: colors.sky[400], + weight: fontWeights.normal, + } }; const shadowAlpha: NumberToken = { - value: 0.32, - type: "number", + value: 0.32, + type: "number", }; const theme: Theme = { - name: "dark", - backgroundColor, - borderColor, - textColor, - iconColor, - editor, - syntax, - player, - shadowAlpha, + name: "dark", + backgroundColor, + borderColor, + textColor, + iconColor, + editor, + syntax, + player, + shadowAlpha, }; export default theme; diff --git a/styles/themes/light.ts b/styles/themes/light.ts index 7a9bf1b552650b81288e70acc6c7500c80a8246b..acb704de74b99b91c2b41a739c751003670c5864 100644 --- a/styles/themes/light.ts +++ b/styles/themes/light.ts @@ -1,143 +1,141 @@ -import core from "../tokens/core"; -import Theme, { NumberToken, Syntax } from "./theme"; - -const { color } = core; +import { colors, fontWeights, NumberToken } from "../tokens"; +import Theme, { Syntax } from "./theme"; // TODO: Replace with light values const backgroundColor = { 100: { - base: color.neutral[750], - hovered: color.neutral[750], - active: color.neutral[750], - focused: color.neutral[750], + base: colors.neutral[750], + hovered: colors.neutral[750], + active: colors.neutral[750], + focused: colors.neutral[750], }, 300: { - base: color.neutral[800], - hovered: color.neutral[800], - active: color.neutral[800], - focused: color.neutral[800], + base: colors.neutral[800], + hovered: colors.neutral[800], + active: colors.neutral[800], + focused: colors.neutral[800], }, 500: { - base: color.neutral[900], - hovered: color.neutral[900], - active: color.neutral[900], - focused: color.neutral[900], + base: colors.neutral[900], + hovered: colors.neutral[900], + active: colors.neutral[900], + focused: colors.neutral[900], }, ok: { - base: color.green[600], - hovered: color.green[600], - active: color.green[600], - focused: color.green[600], + base: colors.green[600], + hovered: colors.green[600], + active: colors.green[600], + focused: colors.green[600], }, error: { - base: color.red[400], - hovered: color.red[400], - active: color.red[400], - focused: color.red[400], + base: colors.red[400], + hovered: colors.red[400], + active: colors.red[400], + focused: colors.red[400], }, warning: { - base: color.amber[300], - hovered: color.amber[300], - active: color.amber[300], - focused: color.amber[300], + base: colors.amber[300], + hovered: colors.amber[300], + active: colors.amber[300], + focused: colors.amber[300], }, info: { - base: color.blue[500], - hovered: color.blue[500], - active: color.blue[500], - focused: color.blue[500], + base: colors.blue[500], + hovered: colors.blue[500], + active: colors.blue[500], + focused: colors.blue[500], }, }; const borderColor = { - primary: color.neutral[850], - secondary: color.neutral[700], - muted: color.neutral[750], - focused: color.neutral[100], - active: color.neutral[500], - ok: color.neutral[1000], - error: color.neutral[1000], - warning: color.neutral[1000], - info: color.neutral[1000], + primary: colors.neutral[850], + secondary: colors.neutral[700], + muted: colors.neutral[750], + focused: colors.neutral[100], + active: colors.neutral[500], + ok: colors.neutral[1000], + error: colors.neutral[1000], + warning: colors.neutral[1000], + info: colors.neutral[1000], }; const textColor = { - primary: color.neutral[150], - secondary: color.neutral[350], - muted: color.neutral[550], - placeholder: color.neutral[750], - active: color.neutral[0], + primary: colors.neutral[150], + secondary: colors.neutral[350], + muted: colors.neutral[550], + placeholder: colors.neutral[750], + active: colors.neutral[0], //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + feature: colors.sky[500], + ok: colors.green[600], + error: colors.red[400], + warning: colors.amber[300], + info: colors.blue[500], }; const iconColor = { - primary: color.neutral[300], - secondary: color.neutral[500], - muted: color.neutral[600], - placeholder: color.neutral[700], - active: color.neutral[50], + primary: colors.neutral[300], + secondary: colors.neutral[500], + muted: colors.neutral[600], + placeholder: colors.neutral[700], + active: colors.neutral[50], //TODO: (design) define feature and it's correct value - feature: color.sky[500], - ok: color.green[600], - error: color.red[400], - warning: color.amber[300], - info: color.blue[500], + feature: colors.sky[500], + ok: colors.green[600], + error: colors.red[400], + warning: colors.amber[300], + info: colors.blue[500], }; const player = { 1: { - baseColor: color.blue[600], - cursorColor: color.blue[600], - selectionColor: color.blue[600], - borderColor: color.blue[600], + baseColor: colors.blue[600], + cursorColor: colors.blue[600], + selectionColor: colors.blue[600], + borderColor: colors.blue[600], }, 2: { - baseColor: color.indigo[500], - cursorColor: color.indigo[500], - selectionColor: color.indigo[500], - borderColor: color.indigo[500], + baseColor: colors.indigo[500], + cursorColor: colors.indigo[500], + selectionColor: colors.indigo[500], + borderColor: colors.indigo[500], }, 3: { - baseColor: color.green[500], - cursorColor: color.green[500], - selectionColor: color.green[500], - borderColor: color.green[500], + baseColor: colors.green[500], + cursorColor: colors.green[500], + selectionColor: colors.green[500], + borderColor: colors.green[500], }, 4: { - baseColor: color.orange[500], - cursorColor: color.orange[500], - selectionColor: color.orange[500], - borderColor: color.orange[500], + baseColor: colors.orange[500], + cursorColor: colors.orange[500], + selectionColor: colors.orange[500], + borderColor: colors.orange[500], }, 5: { - baseColor: color.purple[500], - cursorColor: color.purple[500], - selectionColor: color.purple[500], - borderColor: color.purple[500], + baseColor: colors.purple[500], + cursorColor: colors.purple[500], + selectionColor: colors.purple[500], + borderColor: colors.purple[500], }, 6: { - baseColor: color.teal[400], - cursorColor: color.teal[400], - selectionColor: color.teal[400], - borderColor: color.teal[400], + baseColor: colors.teal[400], + cursorColor: colors.teal[400], + selectionColor: colors.teal[400], + borderColor: colors.teal[400], }, 7: { - baseColor: color.pink[400], - cursorColor: color.pink[400], - selectionColor: color.pink[400], - borderColor: color.pink[400], + baseColor: colors.pink[400], + cursorColor: colors.pink[400], + selectionColor: colors.pink[400], + borderColor: colors.pink[400], }, 8: { - baseColor: color.yellow[400], - cursorColor: color.yellow[400], - selectionColor: color.yellow[400], - borderColor: color.yellow[400], + baseColor: colors.yellow[400], + cursorColor: colors.yellow[400], + selectionColor: colors.yellow[400], + borderColor: colors.yellow[400], }, }; @@ -147,88 +145,114 @@ const editor = { indent_guide: borderColor.muted, indent_guide_active: borderColor.secondary, line: { - active: color.neutral[0], - highlighted: color.neutral[0], - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, + active: colors.neutral[0], + highlighted: colors.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, }, highlight: { - selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: color.neutral[0], - matchingBracket: color.neutral[0], - match: color.neutral[0], - activeMatch: color.neutral[0], - related: color.neutral[0], + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: colors.neutral[0], + matchingBracket: colors.neutral[0], + match: colors.neutral[0], + activeMatch: colors.neutral[0], + related: colors.neutral[0], }, gutter: { - primary: color.neutral[0], - active: color.neutral[0], + primary: colors.neutral[0], + active: colors.neutral[0], }, }; const syntax: Syntax = { primary: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, + color: textColor.primary, + weight: fontWeights.normal, }, comment: { - color: color.lime[200], - weight: { value: "normal", type: "fontWeight" }, + color: colors.lime[200], + weight: fontWeights.normal, }, punctuation: { - color: textColor.primary, - weight: { value: "normal", type: "fontWeight" }, + color: textColor.primary, + weight: fontWeights.normal, }, constant: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, + color: colors.neutral[150], + weight: fontWeights.normal, }, keyword: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, + color: colors.sky[400], + weight: fontWeights.normal, }, function: { - color: color.yellow[200], - weight: { value: "normal", type: "fontWeight" }, + color: colors.yellow[200], + weight: fontWeights.normal, }, type: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, + color: colors.teal[300], + weight: fontWeights.normal, }, variant: { - color: color.teal[300], - weight: { value: "normal", type: "fontWeight" }, + color: colors.teal[300], + weight: fontWeights.normal, }, property: { - color: color.sky[300], - weight: { value: "normal", type: "fontWeight" }, + color: colors.sky[300], + weight: fontWeights.normal, }, enum: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, + color: colors.sky[400], + weight: fontWeights.normal, }, operator: { - color: color.sky[400], - weight: { value: "normal", type: "fontWeight" }, + color: colors.sky[400], + weight: fontWeights.normal, }, string: { - color: color.orange[300], - weight: { value: "normal", type: "fontWeight" }, + color: colors.orange[300], + weight: fontWeights.normal, }, number: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, + color: colors.neutral[150], + weight: fontWeights.normal, }, boolean: { - color: color.neutral[150], - weight: { value: "normal", type: "fontWeight" }, + color: colors.neutral[150], + weight: fontWeights.normal, }, predictive: { - color: textColor.muted, - weight: { value: "normal", type: "fontWeight" }, - }, + color: textColor.muted, + weight: fontWeights.normal, + }, + title: { + color: colors.sky[500], + weight: fontWeights.bold, + }, + emphasis: { + color: textColor.active, + weight: fontWeights.normal, + }, + emphasisStrong: { + color: textColor.active, + weight: fontWeights.bold, + }, + linkUrl: { + color: colors.lime[500], + weight: fontWeights.normal, + // TODO: add underline + }, + linkText: { + color: colors.orange[500], + weight: fontWeights.normal, + // TODO: add italic + }, + listMarker: { + color: colors.sky[400], + weight: fontWeights.normal, + } }; const shadowAlpha: NumberToken = { diff --git a/styles/themes/theme.ts b/styles/themes/theme.ts index a7760459897b0bedec0d87512e669d1d7ae0a3b4..f95d58e49484aea340693ff289f19cb8cf8a4b0a 100644 --- a/styles/themes/theme.ts +++ b/styles/themes/theme.ts @@ -1,32 +1,8 @@ -export interface NumberToken { - value: number, - type: "number" -} - -export type Color = string; -export interface ColorToken { - value: Color; - type: "color"; - step?: number -} -export type Weight = - | "thin" - | "extra_light" - | "light" - | "normal" - | "medium" - | "semibold" - | "bold" - | "extra_bold" - | "black"; -export interface WeightToken { - value: Weight, - type: "fontWeight" -} +import { FontWeightToken, ColorToken, NumberToken } from "../tokens"; export interface SyntaxHighlightStyle { color: ColorToken; - weight: WeightToken; + weight: FontWeightToken; } export interface Player { @@ -43,7 +19,7 @@ export interface BackgroundColor { focused: ColorToken; } -export interface Syntax { +export interface Syntax { primary: SyntaxHighlightStyle; comment: SyntaxHighlightStyle; punctuation: SyntaxHighlightStyle; @@ -59,6 +35,13 @@ export interface Syntax { number: SyntaxHighlightStyle; boolean: SyntaxHighlightStyle; predictive: SyntaxHighlightStyle; + // TODO: Either move the following or rename + title: SyntaxHighlightStyle; + emphasis: SyntaxHighlightStyle; + emphasisStrong: SyntaxHighlightStyle; + linkUrl: SyntaxHighlightStyle; + linkText: SyntaxHighlightStyle; + listMarker: SyntaxHighlightStyle; }; export default interface Theme { diff --git a/styles/tokens.ts b/styles/tokens.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e0df5032d09ee72ce31fc2b9de256174b6bf905 --- /dev/null +++ b/styles/tokens.ts @@ -0,0 +1,102 @@ +import { colorRamp } from "./utils/color"; + +interface Token { + value: V, + type: T +} + +export type FontFamily = string; +export type FontFamilyToken = Token; +function fontFamily(value: FontFamily): FontFamilyToken { + return { + value, + type: "fontFamily" + } +} +export const fontFamilies = { + sans: fontFamily("Zed Sans"), + mono: fontFamily("Zed Mono"), +} + +export type FontSize = number; +export type FontSizeToken = Token; +function fontSize(value: FontSize) { + return { + value, + type: "fontSize" + }; +} +export const fontSizes = { + "3xs": fontSize(8), + "2xs": fontSize(10), + xs: fontSize(12), + sm: fontSize(14), + md: fontSize(16), + lg: fontSize(18), + xl: fontSize(20), +}; + +export type FontWeight = + | "thin" + | "extra_light" + | "light" + | "normal" + | "medium" + | "semibold" + | "bold" + | "extra_bold" + | "black"; +export type FontWeightToken = Token; +function fontWeight(value: FontWeight): FontWeightToken { + return { + value, + type: "fontWeight" + }; +} +export const fontWeights = { + "thin": fontWeight("thin"), + "extra_light": fontWeight("extra_light"), + "light": fontWeight("light"), + "normal": fontWeight("normal"), + "medium": fontWeight("medium"), + "semibold": fontWeight("semibold"), + "bold": fontWeight("bold"), + "extra_bold": fontWeight("extra_bold"), + "black": fontWeight("black"), +} + +export type Color = string; +export interface ColorToken { + value: Color, + type: "color", + step?: number, +} +export const colors = { + neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), + rose: colorRamp("#F43F5EFF"), + red: colorRamp("#EF4444FF"), + orange: colorRamp("#F97316FF"), + amber: colorRamp("#F59E0BFF"), + yellow: colorRamp("#EAB308FF"), + lime: colorRamp("#84CC16FF"), + green: colorRamp("#22C55EFF"), + emerald: colorRamp("#10B981FF"), + teal: colorRamp("#14B8A6FF"), + cyan: colorRamp("#06BBD4FF"), + sky: colorRamp("#0EA5E9FF"), + blue: colorRamp("#3B82F6FF"), + indigo: colorRamp("#6366F1FF"), + violet: colorRamp("#8B5CF6FF"), + purple: colorRamp("#A855F7FF"), + fuschia: colorRamp("#D946E4FF"), + pink: colorRamp("#EC4899FF"), +} + +export type NumberToken = Token; + +export default { + fontFamilies, + fontSizes, + fontWeights, + colors, +}; diff --git a/styles/tokens/core.ts b/styles/tokens/core.ts deleted file mode 100644 index 38bfe82e28129954a2f5602038d575a3cfbb94af..0000000000000000000000000000000000000000 --- a/styles/tokens/core.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { colorRamp } from "../utils/color"; - -export default { - fontFamily: { - sans: "Zed Sans", - mono: "Zed Mono", - }, - fontSize: { - "3xs": { - value: "8", - type: "fontSizes", - }, - "2xs": { - value: "10", - type: "fontSizes", - }, - xs: { - value: "12", - type: "fontSizes", - }, - sm: { - value: "14", - type: "fontSizes", - }, - md: { - value: "16", - type: "fontSizes", - }, - lg: { - value: "18", - type: "fontSizes", - }, - xl: { - value: "20", - type: "fontSizes", - }, - }, - color: { - neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), - rose: colorRamp("#F43F5EFF"), - red: colorRamp("#EF4444FF"), - orange: colorRamp("#F97316FF"), - amber: colorRamp("#F59E0BFF"), - yellow: colorRamp("#EAB308FF"), - lime: colorRamp("#84CC16FF"), - green: colorRamp("#22C55EFF"), - emerald: colorRamp("#10B981FF"), - teal: colorRamp("#14B8A6FF"), - cyan: colorRamp("#06BBD4FF"), - sky: colorRamp("#0EA5E9FF"), - blue: colorRamp("#3B82F6FF"), - indigo: colorRamp("#6366F1FF"), - violet: colorRamp("#8B5CF6FF"), - purple: colorRamp("#A855F7FF"), - fuschia: colorRamp("#D946E4FF"), - pink: colorRamp("#EC4899FF"), - }, -}; From c812adde7f893b932fcd7fc7df401c5a83515ea4 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 1 Apr 2022 22:39:18 -0400 Subject: [PATCH 59/68] Add "npm run watch" command to live reload changes --- styles/nodemon.json | 6 + styles/package-lock.json | 2501 ++++++++++++++++++++++++++++++++++++-- styles/package.json | 6 +- 3 files changed, 2398 insertions(+), 115 deletions(-) create mode 100644 styles/nodemon.json diff --git a/styles/nodemon.json b/styles/nodemon.json new file mode 100644 index 0000000000000000000000000000000000000000..24022a55ad3aa2137a6fec03cdc1c97fa4e59e76 --- /dev/null +++ b/styles/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./**/*"], + "ext": "ts", + "ignore": [], + "exec": "ts-node buildThemes.ts" +} \ No newline at end of file diff --git a/styles/package-lock.json b/styles/package-lock.json index 582f1c84968a5c1a25ddac5fd3c21ba907353c6d..43c9b19ea1224415c654186ed6203c48e776e2da 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -12,7 +12,10 @@ "@types/chroma-js": "^2.1.3", "@types/node": "^17.0.23", "case-anything": "^2.1.10", - "chroma-js": "^2.4.2", + "chroma-js": "^2.4.2" + }, + "devDependencies": { + "nodemon": "^2.0.15", "ts-node": "^10.7.0" } }, @@ -20,6 +23,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, "engines": { "node": ">= 12" } @@ -28,6 +32,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, "dependencies": { "@cspotcode/source-map-consumer": "0.8.0" }, @@ -35,25 +40,50 @@ "node": ">=12" } }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true }, "node_modules/@types/chroma-js": { "version": "2.1.3", @@ -65,10 +95,17 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -80,14 +117,175 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, "engines": { "node": ">=0.4.0" } }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/case-anything": { "version": "2.1.10", @@ -100,186 +298,2136 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, "engines": { "node": ">=0.3.1" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" + "is-obj": "^2.0.0" }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } + "engines": { + "node": ">=6" } }, - "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4.2.0" + "node": ">= 6" } }, - "node_modules/v8-compile-cache-lib": { + "node_modules/global-dirs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": ">=8.6" } - } - }, - "dependencies": { - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" } }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true }, - "@tsconfig/node14": { + "node_modules/ignore-by-default": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } }, - "@types/chroma-js": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", - "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nodemon": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/chroma-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.1.3.tgz", + "integrity": "sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g==" + }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true }, "case-anything": { "version": "2.1.10", "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz", "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ==" }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chroma-js": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nodemon": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } }, "ts-node": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, "requires": { "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", @@ -296,21 +2444,146 @@ "yn": "3.1.1" } }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, "peer": true }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, "v8-compile-cache-lib": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/styles/package.json b/styles/package.json index c270bba0e1563cee758bbf5a02fb9fc1848b37ae..8576a35d34956a0dd438e35f6989dd9b68b217c2 100644 --- a/styles/package.json +++ b/styles/package.json @@ -4,7 +4,8 @@ "description": "", "main": "index.js", "scripts": { - "build": "ts-node buildThemes.ts" + "build": "ts-node buildThemes.ts", + "watch": "nodemon" }, "author": "", "license": "ISC", @@ -14,5 +15,8 @@ "case-anything": "^2.1.10", "chroma-js": "^2.4.2", "ts-node": "^10.7.0" + }, + "devDependencies": { + "nodemon": "^2.0.15" } } From 381d50bac62fee058721839a2e983b35445a1ad6 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 1 Apr 2022 23:58:04 -0400 Subject: [PATCH 60/68] WIP --- crates/zed/assets/themes/dark.json | 351 ++++++++++++------------ crates/zed/assets/themes/light.json | 411 ++++++++++++++-------------- styles/buildThemes.ts | 2 +- styles/styleTree/chatPanel.ts | 8 +- styles/styleTree/editor.ts | 14 +- styles/styleTree/projectPanel.ts | 7 +- styles/styleTree/workspace.ts | 29 +- styles/themes/dark.ts | 24 +- styles/themes/light.ts | 288 ++++++++++--------- styles/themes/theme.ts | 2 +- styles/tokens.ts | 2 +- 11 files changed, 576 insertions(+), 562 deletions(-) diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json index 65bf78b140ff3c94c298982cf2b3a6f6b8210609..fd11fc6c3a64a6fd6d878b935941d21960c12f37 100644 --- a/crates/zed/assets/themes/dark.json +++ b/crates/zed/assets/themes/dark.json @@ -1,6 +1,6 @@ { "selector": { - "background": "#e6e6e6", + "background": "#000000", "corner_radius": 6, "padding": 8, "item": { @@ -13,12 +13,12 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#90df17", "weight": "bold", "size": 14 } @@ -33,25 +33,25 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#90df17", "weight": "bold", "size": 14 }, - "background": "#e6e6e6" + "background": "#000000" }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "empty": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "padding": { @@ -62,11 +62,11 @@ } }, "input_editor": { - "background": "#cccccc", + "background": "#1c1c1c", "corner_radius": 6, "placeholder_text": { "family": "Zed Sans", - "color": "#bfbfbf", + "color": "#2b2b2b", "size": 14 }, "selection": { @@ -75,11 +75,11 @@ }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16 }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "padding": { @@ -103,24 +103,25 @@ } }, "workspace": { - "background": "#e6e6e6", + "background": "#1c1c1c", "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { - "height": 34, - "icon_close": "#808080", - "icon_close_active": "#0d0d0d", - "icon_conflict": "#f8c570", - "icon_dirty": "#6099f7", + "height": 32, + "background": "#1c1c1c", + "icon_close": "#717171", + "icon_close_active": "#f1f1f1", + "icon_conflict": "#f7b241", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#9c9c9c", + "size": 14 }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "left": true, "bottom": true, @@ -132,20 +133,21 @@ } }, "active_tab": { - "height": 34, - "icon_close": "#808080", - "icon_close_active": "#0d0d0d", - "icon_conflict": "#f8c570", - "icon_dirty": "#6099f7", + "height": 32, + "background": "#000000", + "icon_close": "#717171", + "icon_close_active": "#f1f1f1", + "icon_conflict": "#f7b241", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#ffffff", + "size": 14 }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "left": true, "bottom": false, @@ -154,28 +156,28 @@ "padding": { "left": 12, "right": 12 - }, - "background": "#cccccc" + } }, "left_sidebar": { "width": 30, + "background": "#1c1c1c", "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "right": true }, "item": { "height": 32, - "icon_color": "#808080", + "icon_color": "#717171", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#4d4d4d", + "icon_color": "#f1f1f1", "icon_size": 18 }, "resize_handle": { - "background": "#d9d9d9", + "background": "#0e0e0e", "padding": { "left": 1 } @@ -183,30 +185,31 @@ }, "right_sidebar": { "width": 30, + "background": "#1c1c1c", "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "left": true }, "item": { "height": 32, - "icon_color": "#808080", + "icon_color": "#717171", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#4d4d4d", + "icon_color": "#f1f1f1", "icon_size": 18 }, "resize_handle": { - "background": "#d9d9d9", + "background": "#0e0e0e", "padding": { "left": 1 } } }, "pane_divider": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "status_bar": { @@ -218,28 +221,29 @@ }, "cursor_position": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "diagnostic_message": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "lsp_message": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 } }, "titlebar": { "avatar_width": 18, "height": 32, - "share_icon_color": "#808080", - "share_icon_active_color": "#0d0d0d", + "background": "#393939", + "share_icon_color": "#717171", + "share_icon_active_color": "#f1f1f1", "title": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "avatar": { @@ -254,13 +258,13 @@ "width": 12 }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "bottom": true }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 13, "underline": true, "padding": { @@ -269,15 +273,15 @@ }, "hovered_sign_in_prompt": { "family": "Zed Mono", - "color": "#000000", - "size": 16, + "color": "#ffffff", + "size": 13, "underline": true, "padding": { "right": 8 } }, "offline_icon": { - "color": "#999999", + "color": "#717171", "width": 16, "padding": { "right": 4 @@ -285,15 +289,15 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#f8c570", "size": 13 } }, "toolbar": { "height": 34, - "background": "#cccccc", + "background": "#000000", "border": { - "color": "#d9d9d9", + "color": "#2b2b2b", "width": 1, "bottom": true }, @@ -307,7 +311,7 @@ }, "breadcrumbs": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, "padding": { "left": 6 @@ -321,20 +325,20 @@ } }, "editor": { - "text_color": "#595959", - "background": "#cccccc", - "active_line_background": "#000000", - "code_actions_indicator": "#808080", + "text_color": "#9c9c9c", + "background": "#000000", + "active_line_background": "#ffffff", + "code_actions_indicator": "#717171", "diff_background_deleted": "#f78c8c", "diff_background_inserted": "#22c55e", - "document_highlight_read_background": "#e6e6e6", - "document_highlight_write_background": "#e6e6e6", + "document_highlight_read_background": "#000000", + "document_highlight_write_background": "#000000", "error_color": "#f78c8c", - "gutter_background": "#cccccc", + "gutter_background": "#000000", "gutter_padding_factor": 2.5, - "highlighted_line_background": "#000000", - "line_number": "#000000", - "line_number_active": "#000000", + "highlighted_line_background": "#ffffff", + "line_number": "#ffffff", + "line_number_active": "#ffffff", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { @@ -372,11 +376,11 @@ } ], "autocomplete": { - "background": "#bfbfbf", + "background": "#000000", "corner_radius": 6, "padding": 6, "border": { - "color": "#b3b3b3", + "color": "#393939", "width": 1 }, "item": { @@ -396,7 +400,7 @@ "right": 6, "top": 2 }, - "background": "#bfbfbf" + "background": "#000000" }, "margin": { "left": -14 @@ -413,22 +417,22 @@ "right": 6, "top": 2 }, - "background": "#bfbfbf" + "background": "#000000" } }, "diagnostic_header": { - "background": "#e6e6e6", + "background": "#1c1c1c", "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#b3b3b3", + "color": "#393939", "width": 1, "bottom": true, "top": true }, "code": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "left": 10 @@ -437,28 +441,28 @@ "message": { "highlight_text": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14, "weight": "bold" }, "text": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 14 } } }, "diagnostic_path_header": { - "background": "#000000", + "background": "#ffffff", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "path": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "left": 12 @@ -469,7 +473,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -492,7 +496,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -515,7 +519,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -538,7 +542,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -561,7 +565,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -569,12 +573,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "weight": "bold" } @@ -584,7 +588,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -592,12 +596,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "weight": "bold" } @@ -607,7 +611,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -615,12 +619,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "weight": "bold" } @@ -630,7 +634,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1, "top": true } @@ -638,12 +642,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "weight": "bold" } @@ -652,18 +656,18 @@ "syntax": {} }, "project_diagnostics": { - "background": "#cccccc", + "background": "#1c1c1c", "tab_icon_spacing": 4, "tab_icon_width": 13, "tab_summary_spacing": 10, "empty_message": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "status_bar_item": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 10 @@ -672,52 +676,53 @@ }, "project_panel": { "padding": { - "top": 6 + "top": 6, + "left": 12 }, "entry": { "height": 22, - "icon_color": "#999999", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#9c9c9c", + "size": 14 } }, "hovered_entry": { "height": 22, - "background": "#cccccc", - "icon_color": "#999999", + "background": "#1c1c1c", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#9c9c9c", + "size": 14 } }, "selected_entry": { "height": 22, - "icon_color": "#999999", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#d5d5d5", + "size": 14 } }, "hovered_selected_entry": { "height": 22, - "background": "#cccccc", - "icon_color": "#999999", + "background": "#1c1c1c", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#d5d5d5", + "size": 14 } } }, @@ -730,13 +735,13 @@ }, "channel_name": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "weight": "bold", "size": 14 }, "channel_name_hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "padding": { "right": 8 @@ -746,7 +751,7 @@ "header": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "padding": { @@ -755,7 +760,7 @@ }, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 8 @@ -766,13 +771,13 @@ "item": { "name": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 8 @@ -783,31 +788,31 @@ "hovered_item": { "name": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 8 } }, - "background": "#cccccc", + "background": "#1c1c1c", "corner_radius": 6 }, "active_item": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 8 @@ -818,27 +823,27 @@ "hovered_active_item": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14, "margin": { "right": 8 } }, - "background": "#cccccc", + "background": "#1c1c1c", "corner_radius": 6 }, "menu": { - "background": "#e6e6e6", + "background": "#000000", "corner_radius": 6, "padding": 4, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "shadow": { @@ -853,25 +858,25 @@ }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "underline": true, "size": 14 }, "hovered_sign_in_prompt": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "underline": true, "size": 14 }, "message": { "body": { "family": "Zed Sans", - "color": "#595959", + "color": "#9c9c9c", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "padding": { @@ -879,7 +884,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "weight": "bold", "size": 14, "margin": { @@ -890,12 +895,12 @@ "pending_message": { "body": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "size": 14 }, "padding": { @@ -903,7 +908,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#636363", "weight": "bold", "size": 14, "margin": { @@ -912,24 +917,24 @@ } }, "input_editor": { - "background": "#cccccc", + "background": "#000000", "corner_radius": 6, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16 }, "placeholder_text": { "family": "Zed Mono", - "color": "#8c8c8c", - "size": 16 + "color": "#2b2b2b", + "size": 14 }, "selection": { "cursor": "#4287f6", "selection": "#4287f6" }, "border": { - "color": "#d9d9d9", + "color": "#393939", "width": 1 }, "padding": { @@ -948,7 +953,7 @@ "right": 12 }, "host_row_height": 28, - "tree_branch_color": "#bfbfbf", + "tree_branch_color": "#2b2b2b", "tree_branch_width": 1, "host_avatar": { "corner_radius": 10, @@ -956,7 +961,7 @@ }, "host_username": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#636363", "size": 16, "padding": { "left": 8 @@ -971,7 +976,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, "margin": { "right": 6 @@ -990,7 +995,7 @@ }, "name": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16, "margin": { "right": 6 @@ -1009,7 +1014,7 @@ }, "name": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16, "margin": { "right": 6 @@ -1018,7 +1023,7 @@ "padding": { "left": 8 }, - "background": "#000000", + "background": "#ffffff", "corner_radius": 6 }, "unshared_project": { @@ -1030,7 +1035,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, "margin": { "right": 6 @@ -1049,7 +1054,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, "margin": { "right": 6 @@ -1058,22 +1063,22 @@ "padding": { "left": 8 }, - "background": "#000000", + "background": "#ffffff", "corner_radius": 6 } }, "search": { - "match_background": "#000000", + "match_background": "#ffffff", "tab_icon_spacing": 4, "tab_icon_width": 14, "active_hovered_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, - "background": "#bfbfbf", + "background": "#393939", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "margin": { @@ -1089,12 +1094,12 @@ }, "active_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, - "background": "#bfbfbf", + "background": "#393939", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "margin": { @@ -1109,13 +1114,13 @@ } }, "editor": { - "background": "#e6e6e6", + "background": "#000000", "corner_radius": 6, "min_width": 200, "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#bfbfbf", + "color": "#2b2b2b", "size": 16 }, "selection": { @@ -1124,11 +1129,11 @@ }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16 }, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "margin": { @@ -1143,12 +1148,12 @@ }, "hovered_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, - "background": "#bfbfbf", + "background": "#393939", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "margin": { @@ -1163,13 +1168,13 @@ } }, "invalid_editor": { - "background": "#e6e6e6", + "background": "#000000", "corner_radius": 6, "min_width": 200, "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#bfbfbf", + "color": "#2b2b2b", "size": 16 }, "selection": { @@ -1178,11 +1183,11 @@ }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 16 }, "border": { - "color": "#ffffff", + "color": "#f47171", "width": 1 }, "margin": { @@ -1197,18 +1202,18 @@ }, "match_index": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#636363", "size": 16, "padding": 6 }, "option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#9c9c9c", "size": 16, - "background": "#cccccc", + "background": "#1c1c1c", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#0e0e0e", "width": 1 }, "margin": { @@ -1230,13 +1235,13 @@ }, "results_status": { "family": "Zed Mono", - "color": "#262626", + "color": "#d5d5d5", "size": 18 } }, "breadcrumbs": { "family": "Zed Sans", - "color": "#262626", + "color": "#d5d5d5", "size": 14, "padding": { "left": 6 diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json index 65bf78b140ff3c94c298982cf2b3a6f6b8210609..219f958e876dcb36abd4edf2e2986c7fb26f32c3 100644 --- a/crates/zed/assets/themes/light.json +++ b/crates/zed/assets/themes/light.json @@ -1,6 +1,6 @@ { "selector": { - "background": "#e6e6e6", + "background": "#ffffff", "corner_radius": 6, "padding": 8, "item": { @@ -13,12 +13,12 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#4287f6", "weight": "bold", "size": 14 } @@ -33,25 +33,25 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#4287f6", "weight": "bold", "size": 14 }, - "background": "#e6e6e6" + "background": "#e3e3e3" }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "empty": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "padding": { @@ -62,24 +62,24 @@ } }, "input_editor": { - "background": "#cccccc", + "background": "#f1f1f1", "corner_radius": 6, "placeholder_text": { "family": "Zed Sans", - "color": "#bfbfbf", + "color": "#717171", "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16 }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "padding": { @@ -95,7 +95,7 @@ }, "shadow": { "blur": 16, - "color": "#00000052", + "color": "#0000001f", "offset": [ 0, 2 @@ -103,24 +103,25 @@ } }, "workspace": { - "background": "#e6e6e6", + "background": "#f1f1f1", "leader_border_opacity": 0.7, "leader_border_width": 2, "tab": { - "height": 34, - "icon_close": "#808080", - "icon_close_active": "#0d0d0d", - "icon_conflict": "#f8c570", - "icon_dirty": "#6099f7", + "height": 32, + "background": "#f1f1f1", + "icon_close": "#717171", + "icon_close_active": "#000000", + "icon_conflict": "#f6bc09", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#393939", + "size": 14 }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "left": true, "bottom": true, @@ -132,20 +133,21 @@ } }, "active_tab": { - "height": 34, - "icon_close": "#808080", - "icon_close_active": "#0d0d0d", - "icon_conflict": "#f8c570", - "icon_dirty": "#6099f7", + "height": 32, + "background": "#ffffff", + "icon_close": "#717171", + "icon_close_active": "#000000", + "icon_conflict": "#f6bc09", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#000000", + "size": 14 }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "left": true, "bottom": false, @@ -154,28 +156,28 @@ "padding": { "left": 12, "right": 12 - }, - "background": "#cccccc" + } }, "left_sidebar": { "width": 30, + "background": "#f1f1f1", "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "right": true }, "item": { "height": 32, - "icon_color": "#808080", + "icon_color": "#717171", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#4d4d4d", + "icon_color": "#000000", "icon_size": 18 }, "resize_handle": { - "background": "#d9d9d9", + "background": "#c6c6c6", "padding": { "left": 1 } @@ -183,30 +185,31 @@ }, "right_sidebar": { "width": 30, + "background": "#f1f1f1", "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "left": true }, "item": { "height": 32, - "icon_color": "#808080", + "icon_color": "#717171", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#4d4d4d", + "icon_color": "#000000", "icon_size": 18 }, "resize_handle": { - "background": "#d9d9d9", + "background": "#c6c6c6", "padding": { "left": 1 } } }, "pane_divider": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "status_bar": { @@ -218,28 +221,29 @@ }, "cursor_position": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "diagnostic_message": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "lsp_message": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 } }, "titlebar": { "avatar_width": 18, "height": 32, - "share_icon_color": "#808080", - "share_icon_active_color": "#0d0d0d", + "background": "#e3e3e3", + "share_icon_color": "#717171", + "share_icon_active_color": "#000000", "title": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "avatar": { @@ -254,13 +258,13 @@ "width": 12 }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "bottom": true }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 13, "underline": true, "padding": { @@ -270,14 +274,14 @@ "hovered_sign_in_prompt": { "family": "Zed Mono", "color": "#000000", - "size": 16, + "size": 13, "underline": true, "padding": { "right": 8 } }, "offline_icon": { - "color": "#999999", + "color": "#717171", "width": 16, "padding": { "right": 4 @@ -285,15 +289,15 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#b48d14", "size": 13 } }, "toolbar": { "height": 34, - "background": "#cccccc", + "background": "#ffffff", "border": { - "color": "#d9d9d9", + "color": "#f1f1f1", "width": 1, "bottom": true }, @@ -307,7 +311,7 @@ }, "breadcrumbs": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, "padding": { "left": 6 @@ -315,68 +319,68 @@ }, "disconnected_overlay": { "family": "Zed Sans", - "color": "#ffffff", + "color": "#000000", "size": 14, "background": "#000000aa" } }, "editor": { - "text_color": "#595959", - "background": "#cccccc", - "active_line_background": "#000000", - "code_actions_indicator": "#808080", - "diff_background_deleted": "#f78c8c", - "diff_background_inserted": "#22c55e", - "document_highlight_read_background": "#e6e6e6", - "document_highlight_write_background": "#e6e6e6", - "error_color": "#f78c8c", - "gutter_background": "#cccccc", + "text_color": "#393939", + "background": "#ffffff", + "active_line_background": "#ffffff", + "code_actions_indicator": "#717171", + "diff_background_deleted": "#fdd4d4", + "diff_background_inserted": "#befad2", + "document_highlight_read_background": "#e3e3e3", + "document_highlight_write_background": "#e3e3e3", + "error_color": "#d11c1c", + "gutter_background": "#ffffff", "gutter_padding_factor": 2.5, - "highlighted_line_background": "#000000", - "line_number": "#000000", - "line_number_active": "#000000", + "highlighted_line_background": "#ffffff", + "line_number": "#ffffff", + "line_number_active": "#ffffff", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "guest_selections": [ { "cursor": "#777af4", - "selection": "#777af4" + "selection": "#d4d5fd" }, { "cursor": "#23d464", - "selection": "#23d464" + "selection": "#befad2" }, { "cursor": "#f98a3d", - "selection": "#f98a3d" + "selection": "#fde0cd" }, { "cursor": "#b671f8", - "selection": "#b671f8" + "selection": "#e9d4fd" }, { "cursor": "#16ddc7", - "selection": "#16ddc7" + "selection": "#b4faf2" }, { "cursor": "#f58ac0", - "selection": "#f58ac0" + "selection": "#fcd4e8" }, { "cursor": "#f6bc09", - "selection": "#f6bc09" + "selection": "#fceabc" } ], "autocomplete": { - "background": "#bfbfbf", + "background": "#ffffff", "corner_radius": 6, "padding": 6, "border": { - "color": "#b3b3b3", + "color": "#e3e3e3", "width": 1 }, "item": { @@ -396,7 +400,7 @@ "right": 6, "top": 2 }, - "background": "#bfbfbf" + "background": "#f1f1f1" }, "margin": { "left": -14 @@ -413,22 +417,22 @@ "right": 6, "top": 2 }, - "background": "#bfbfbf" + "background": "#e3e3e3" } }, "diagnostic_header": { - "background": "#e6e6e6", + "background": "#f1f1f1", "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#b3b3b3", + "color": "#e3e3e3", "width": 1, "bottom": true, "top": true }, "code": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "left": 10 @@ -437,28 +441,28 @@ "message": { "highlight_text": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14, "weight": "bold" }, "text": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 14 } } }, "diagnostic_path_header": { - "background": "#000000", + "background": "#ffffff", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "path": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "left": 12 @@ -469,7 +473,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -477,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#d11c1c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#d11c1c", "size": 14, "weight": "bold" } @@ -492,7 +496,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -500,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#b48d14", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#b48d14", "size": 14, "weight": "bold" } @@ -515,7 +519,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -523,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#1762db", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#1762db", "size": 14, "weight": "bold" } @@ -538,7 +542,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -546,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#1762db", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#1762db", "size": 14, "weight": "bold" } @@ -561,7 +565,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -569,12 +573,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "weight": "bold" } @@ -584,7 +588,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -592,12 +596,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "weight": "bold" } @@ -607,7 +611,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -615,12 +619,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "weight": "bold" } @@ -630,7 +634,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1, "top": true } @@ -638,12 +642,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "weight": "bold" } @@ -652,18 +656,18 @@ "syntax": {} }, "project_diagnostics": { - "background": "#cccccc", + "background": "#f1f1f1", "tab_icon_spacing": 4, "tab_icon_width": 13, "tab_summary_spacing": 10, "empty_message": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "status_bar_item": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 10 @@ -672,52 +676,53 @@ }, "project_panel": { "padding": { - "top": 6 + "top": 6, + "left": 12 }, "entry": { "height": 22, - "icon_color": "#999999", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#393939", + "size": 14 } }, "hovered_entry": { "height": 22, - "background": "#cccccc", - "icon_color": "#999999", + "background": "#e3e3e3", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#595959", - "size": 16 + "color": "#393939", + "size": 14 } }, "selected_entry": { "height": 22, - "icon_color": "#999999", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#1c1c1c", + "size": 14 } }, "hovered_selected_entry": { "height": 22, - "background": "#cccccc", - "icon_color": "#999999", + "background": "#e3e3e3", + "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#262626", - "size": 16 + "color": "#1c1c1c", + "size": 14 } } }, @@ -730,13 +735,13 @@ }, "channel_name": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "weight": "bold", "size": 14 }, "channel_name_hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "padding": { "right": 8 @@ -746,7 +751,7 @@ "header": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "padding": { @@ -755,7 +760,7 @@ }, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 8 @@ -766,13 +771,13 @@ "item": { "name": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 8 @@ -783,31 +788,31 @@ "hovered_item": { "name": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 8 } }, - "background": "#cccccc", + "background": "#e3e3e3", "corner_radius": 6 }, "active_item": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 8 @@ -818,32 +823,32 @@ "hovered_active_item": { "name": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14, "margin": { "right": 8 } }, - "background": "#cccccc", + "background": "#e3e3e3", "corner_radius": 6 }, "menu": { - "background": "#e6e6e6", + "background": "#ffffff", "corner_radius": 6, "padding": 4, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "shadow": { "blur": 16, - "color": "#00000052", + "color": "#0000001f", "offset": [ 0, 2 @@ -853,25 +858,25 @@ }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "underline": true, "size": 14 }, "hovered_sign_in_prompt": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "underline": true, "size": 14 }, "message": { "body": { "family": "Zed Sans", - "color": "#595959", + "color": "#393939", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "padding": { @@ -879,7 +884,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "weight": "bold", "size": 14, "margin": { @@ -890,12 +895,12 @@ "pending_message": { "body": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "size": 14 }, "padding": { @@ -903,7 +908,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#8c8c8c", + "color": "#555555", "weight": "bold", "size": 14, "margin": { @@ -912,24 +917,24 @@ } }, "input_editor": { - "background": "#cccccc", + "background": "#ffffff", "corner_radius": 6, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16 }, "placeholder_text": { "family": "Zed Mono", - "color": "#8c8c8c", - "size": 16 + "color": "#717171", + "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "border": { - "color": "#d9d9d9", + "color": "#e3e3e3", "width": 1 }, "padding": { @@ -948,7 +953,7 @@ "right": 12 }, "host_row_height": 28, - "tree_branch_color": "#bfbfbf", + "tree_branch_color": "#f1f1f1", "tree_branch_width": 1, "host_avatar": { "corner_radius": 10, @@ -956,7 +961,7 @@ }, "host_username": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#555555", "size": 16, "padding": { "left": 8 @@ -971,7 +976,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, "margin": { "right": 6 @@ -990,7 +995,7 @@ }, "name": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16, "margin": { "right": 6 @@ -1009,7 +1014,7 @@ }, "name": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16, "margin": { "right": 6 @@ -1018,7 +1023,7 @@ "padding": { "left": 8 }, - "background": "#000000", + "background": "#ffffff", "corner_radius": 6 }, "unshared_project": { @@ -1030,7 +1035,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, "margin": { "right": 6 @@ -1049,7 +1054,7 @@ }, "name": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, "margin": { "right": 6 @@ -1058,22 +1063,22 @@ "padding": { "left": 8 }, - "background": "#000000", + "background": "#ffffff", "corner_radius": 6 } }, "search": { - "match_background": "#000000", + "match_background": "#ffffff", "tab_icon_spacing": 4, "tab_icon_width": 14, "active_hovered_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, - "background": "#bfbfbf", + "background": "#e3e3e3", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "margin": { @@ -1089,12 +1094,12 @@ }, "active_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, - "background": "#bfbfbf", + "background": "#e3e3e3", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "margin": { @@ -1109,26 +1114,26 @@ } }, "editor": { - "background": "#e6e6e6", + "background": "#ffffff", "corner_radius": 6, "min_width": 200, "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#bfbfbf", + "color": "#717171", "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16 }, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "margin": { @@ -1143,12 +1148,12 @@ }, "hovered_option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, - "background": "#bfbfbf", + "background": "#e3e3e3", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "margin": { @@ -1163,26 +1168,26 @@ } }, "invalid_editor": { - "background": "#e6e6e6", + "background": "#ffffff", "corner_radius": 6, "min_width": 200, "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#bfbfbf", + "color": "#717171", "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 16 }, "border": { - "color": "#ffffff", + "color": "#fbbdbd", "width": 1 }, "margin": { @@ -1197,18 +1202,18 @@ }, "match_index": { "family": "Zed Mono", - "color": "#8c8c8c", + "color": "#555555", "size": 16, "padding": 6 }, "option_button": { "family": "Zed Mono", - "color": "#595959", + "color": "#393939", "size": 16, - "background": "#cccccc", + "background": "#f1f1f1", "corner_radius": 6, "border": { - "color": "#d9d9d9", + "color": "#c6c6c6", "width": 1 }, "margin": { @@ -1230,13 +1235,13 @@ }, "results_status": { "family": "Zed Mono", - "color": "#262626", + "color": "#1c1c1c", "size": 18 } }, "breadcrumbs": { "family": "Zed Sans", - "color": "#262626", + "color": "#1c1c1c", "size": 14, "padding": { "left": 6 diff --git a/styles/buildThemes.ts b/styles/buildThemes.ts index d67860cee66a0ec7abd7d37da8b10f0a6c930488..9128eff45d46a0a11b9a8ddb04013b3b59faf87a 100644 --- a/styles/buildThemes.ts +++ b/styles/buildThemes.ts @@ -1,8 +1,8 @@ import * as fs from "fs"; import * as path from "path"; +import app from "./styleTree/app"; import dark from "./themes/dark"; import light from "./themes/light"; -import app from "./styleTree/app"; import decamelizeTree from "./utils/decamelizeTree"; const themes = [dark, light]; diff --git a/styles/styleTree/chatPanel.ts b/styles/styleTree/chatPanel.ts index ea9a8ffe22a83e2b7135bc886273f2da2d7c1502..69b5f3baa0d74c03e4ff5e0a81ff4fc6616afdfc 100644 --- a/styles/styleTree/chatPanel.ts +++ b/styles/styleTree/chatPanel.ts @@ -31,7 +31,7 @@ export default function chatPanel(theme: Theme) { const message = { body: text(theme, "sans", "secondary"), - timestamp: text(theme, "sans", "muted"), + timestamp: text(theme, "sans", "muted", { size: "sm" }), padding: { bottom: 6, }, @@ -91,12 +91,12 @@ export default function chatPanel(theme: Theme) { }, }, inputEditor: { - background: backgroundColor(theme, 300), + background: backgroundColor(theme, 500), cornerRadius: 6, text: text(theme, "mono", "primary"), - placeholderText: text(theme, "mono", "muted"), + placeholderText: text(theme, "mono", "placeholder", { size: "sm" }), selection: player(theme, 1).selection, - border: border(theme, "primary"), + border: border(theme, "secondary"), padding: { bottom: 7, left: 8, diff --git a/styles/styleTree/editor.ts b/styles/styleTree/editor.ts index ebc53b405875dab197a3c95d5373732050e9a7a0..eb379ce520bfb5b53b85e5d8e28be639d598a6f9 100644 --- a/styles/styleTree/editor.ts +++ b/styles/styleTree/editor.ts @@ -5,7 +5,7 @@ import { iconColor, player, text, - TextColor, + TextColor } from "./components"; export default function editor(theme: Theme) { @@ -39,7 +39,7 @@ export default function editor(theme: Theme) { return { textColor: theme.textColor.secondary.value, - background: backgroundColor(theme, 300), + background: backgroundColor(theme, 500), activeLineBackground: theme.editor.line.active.value, codeActionsIndicator: iconColor(theme, "secondary"), diffBackgroundDeleted: backgroundColor(theme, "error"), @@ -47,7 +47,7 @@ export default function editor(theme: Theme) { documentHighlightReadBackground: theme.editor.highlight.occurrence.value, documentHighlightWriteBackground: theme.editor.highlight.occurrence.value, errorColor: theme.textColor.error.value, - gutterBackground: backgroundColor(theme, 300), + gutterBackground: backgroundColor(theme, 500), gutterPaddingFactor: 2.5, highlightedLineBackground: theme.editor.line.highlighted.value, lineNumber: theme.editor.gutter.primary.value, @@ -65,14 +65,14 @@ export default function editor(theme: Theme) { player(theme, 8).selection, ], autocomplete: { - background: backgroundColor(theme, 100), + background: backgroundColor(theme, 500), cornerRadius: 6, padding: 6, border: border(theme, "secondary"), item: autocompleteItem, hoveredItem: { ...autocompleteItem, - background: backgroundColor(theme, 100, "hovered"), + background: backgroundColor(theme, 500, "hovered"), }, margin: { left: -14, @@ -83,11 +83,11 @@ export default function editor(theme: Theme) { }, selectedItem: { ...autocompleteItem, - background: backgroundColor(theme, 100, "active"), + background: backgroundColor(theme, 500, "active"), }, }, diagnosticHeader: { - background: theme.editor.background.value, + background: backgroundColor(theme, 300), iconWidthFactor: 1.5, textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. border: border(theme, "secondary", { diff --git a/styles/styleTree/projectPanel.ts b/styles/styleTree/projectPanel.ts index cd6fb49b3ada1db47b3dd15637cb1a4a6c5ee516..e27cd94414a031f64dbc0ee5e232d2666944462a 100644 --- a/styles/styleTree/projectPanel.ts +++ b/styles/styleTree/projectPanel.ts @@ -1,7 +1,7 @@ -import { panel } from "./app"; -import { backgroundColor, iconColor, text, TextColor } from "./components"; import Theme from "../themes/theme"; import { Color } from "../utils/color"; +import { panel } from "./app"; +import { backgroundColor, iconColor, text, TextColor } from "./components"; export default function projectPanel(theme: Theme) { function entry(theme: Theme, textColor: TextColor, background?: Color) { @@ -11,7 +11,7 @@ export default function projectPanel(theme: Theme) { iconColor: iconColor(theme, "muted"), iconSize: 8, iconSpacing: 8, - text: text(theme, "mono", textColor), + text: text(theme, "mono", textColor, { size: "sm" }), }; } @@ -31,6 +31,7 @@ export default function projectPanel(theme: Theme) { ), padding: { top: 6, + left: 12, }, }; } diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index 7e71eaad2a8e258e5aed2476af0b68fbf9c7ba4b..a734528d744c21896cb73c090b482615bb3544b3 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -12,14 +12,15 @@ export default function workspace(theme: Theme) { }; const tab = { - height: 34, + height: 32, + background: backgroundColor(theme, 300), iconClose: iconColor(theme, "secondary"), iconCloseActive: iconColor(theme, "active"), iconConflict: iconColor(theme, "warning"), iconDirty: iconColor(theme, "info"), iconWidth: 8, spacing: 10, - text: text(theme, "mono", "secondary"), + text: text(theme, "mono", "secondary", { size: "sm" }), border: border(theme, "primary", { left: true, bottom: true, @@ -33,8 +34,8 @@ export default function workspace(theme: Theme) { const activeTab = { ...tab, - background: backgroundColor(theme, 300), - text: text(theme, "mono", "primary"), + background: backgroundColor(theme, 500), + text: text(theme, "mono", "active", { size: "sm" }), border: { ...tab.border, bottom: false, @@ -48,11 +49,12 @@ export default function workspace(theme: Theme) { }; const sidebar = { width: 30, + background: backgroundColor(theme, 300), border: border(theme, "primary", { right: true }), item: sidebarItem, activeItem: { ...sidebarItem, - iconColor: iconColor(theme, "primary"), + iconColor: iconColor(theme, "active"), }, resizeHandle: { background: border(theme, "primary").color, @@ -63,7 +65,7 @@ export default function workspace(theme: Theme) { }; return { - background: backgroundColor(theme, 500), + background: backgroundColor(theme, 300), leaderBorderOpacity: 0.7, leaderBorderWidth: 2.0, tab, @@ -94,6 +96,7 @@ export default function workspace(theme: Theme) { titlebar: { avatarWidth: 18, height: 32, + background: backgroundColor(theme, 100), shareIconColor: iconColor(theme, "secondary"), shareIconActiveColor: iconColor(theme, "active"), title: text(theme, "sans", "primary"), @@ -107,29 +110,32 @@ export default function workspace(theme: Theme) { avatarRibbon: { height: 3, width: 12, + // TODO: The background for this ideally should be + // set with a token, not hardcoded in rust }, border: border(theme, "primary", { bottom: true }), signInPrompt, hoveredSignInPrompt: { ...signInPrompt, ...text(theme, "mono", "active"), + size: 13, }, offlineIcon: { - color: iconColor(theme, "muted"), + color: iconColor(theme, "secondary"), width: 16, padding: { right: 4, }, }, outdatedWarning: { - ...text(theme, "sans", "muted"), + ...text(theme, "sans", "warning"), size: 13, }, }, toolbar: { height: 34, - background: backgroundColor(theme, 300), - border: border(theme, "primary", { bottom: true }), + background: backgroundColor(theme, 500), + border: border(theme, "muted", { bottom: true }), itemSpacing: 8, padding: { left: 16, right: 8, top: 4, bottom: 4 }, }, @@ -138,8 +144,7 @@ export default function workspace(theme: Theme) { padding: { left: 6 }, }, disconnectedOverlay: { - ...text(theme, "sans", "primary"), - color: "#ffffff", + ...text(theme, "sans", "active"), background: "#000000aa", }, }; diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index 2cadf24601f47cc1172c4d9be753cc80c3a9f20c..f8e0c0fcb6b00e157bf577fca2024ca286561c5d 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -3,10 +3,10 @@ import Theme, { Syntax } from "./theme"; const backgroundColor = { 100: { - base: colors.neutral[750], - hovered: colors.neutral[750], - active: colors.neutral[750], - focused: colors.neutral[750], + base: colors.neutral[700], + hovered: colors.neutral[700], + active: colors.neutral[700], + focused: colors.neutral[700], }, 300: { base: colors.neutral[800], @@ -52,10 +52,10 @@ const borderColor = { muted: colors.neutral[750], focused: colors.neutral[100], active: colors.neutral[500], - ok: colors.neutral[1000], - error: colors.neutral[1000], - warning: colors.neutral[1000], - info: colors.neutral[1000], + ok: colors.green[500], + error: colors.red[500], + warning: colors.amber[500], + info: colors.blue[500], }; const textColor = { @@ -65,7 +65,7 @@ const textColor = { placeholder: colors.neutral[750], active: colors.neutral[0], //TODO: (design) define feature and it's correct value - feature: colors.sky[500], + feature: colors.lime[400], ok: colors.green[600], error: colors.red[400], warning: colors.amber[300], @@ -81,9 +81,9 @@ const iconColor = { //TODO: (design) define feature and it's correct value feature: colors.sky[500], ok: colors.green[600], - error: colors.red[400], - warning: colors.amber[300], - info: colors.blue[500], + error: colors.red[500], + warning: colors.amber[400], + info: colors.blue[600], }; const player = { diff --git a/styles/themes/light.ts b/styles/themes/light.ts index acb704de74b99b91c2b41a739c751003670c5864..c543c78a302e3579970998ad1fb23847b1e1f694 100644 --- a/styles/themes/light.ts +++ b/styles/themes/light.ts @@ -5,73 +5,72 @@ import Theme, { Syntax } from "./theme"; const backgroundColor = { 100: { - base: colors.neutral[750], - hovered: colors.neutral[750], - active: colors.neutral[750], - focused: colors.neutral[750], + base: colors.neutral[100], + hovered: colors.neutral[150], + active: colors.neutral[200], + focused: colors.neutral[150], }, 300: { - base: colors.neutral[800], - hovered: colors.neutral[800], - active: colors.neutral[800], - focused: colors.neutral[800], + base: colors.neutral[50], + hovered: colors.neutral[100], + active: colors.neutral[150], + focused: colors.neutral[100], }, 500: { - base: colors.neutral[900], - hovered: colors.neutral[900], - active: colors.neutral[900], - focused: colors.neutral[900], + base: colors.neutral[0], + hovered: colors.neutral[50], + active: colors.neutral[100], + focused: colors.neutral[50], }, ok: { - base: colors.green[600], - hovered: colors.green[600], - active: colors.green[600], - focused: colors.green[600], + base: colors.green[100], + hovered: colors.green[100], + active: colors.green[100], + focused: colors.green[100], }, error: { - base: colors.red[400], - hovered: colors.red[400], - active: colors.red[400], - focused: colors.red[400], + base: colors.red[100], + hovered: colors.red[100], + active: colors.red[100], + focused: colors.red[100], }, warning: { - base: colors.amber[300], - hovered: colors.amber[300], - active: colors.amber[300], - focused: colors.amber[300], + base: colors.yellow[100], + hovered: colors.yellow[100], + active: colors.yellow[100], + focused: colors.yellow[100], }, info: { - base: colors.blue[500], - hovered: colors.blue[500], - active: colors.blue[500], - focused: colors.blue[500], + base: colors.blue[100], + hovered: colors.blue[100], + active: colors.blue[100], + focused: colors.blue[100], }, }; const borderColor = { - primary: colors.neutral[850], - secondary: colors.neutral[700], - muted: colors.neutral[750], + primary: colors.neutral[200], + secondary: colors.neutral[100], + muted: colors.neutral[50], focused: colors.neutral[100], - active: colors.neutral[500], - ok: colors.neutral[1000], - error: colors.neutral[1000], - warning: colors.neutral[1000], - info: colors.neutral[1000], + active: colors.neutral[250], + ok: colors.green[200], + error: colors.red[200], + warning: colors.yellow[200], + info: colors.blue[200], }; const textColor = { - primary: colors.neutral[150], - secondary: colors.neutral[350], - muted: colors.neutral[550], - placeholder: colors.neutral[750], - active: colors.neutral[0], - //TODO: (design) define feature and it's correct value - feature: colors.sky[500], - ok: colors.green[600], - error: colors.red[400], - warning: colors.amber[300], - info: colors.blue[500], + primary: colors.neutral[800], + secondary: colors.neutral[700], + muted: colors.neutral[600], + placeholder: colors.neutral[500], + active: colors.neutral[900], + feature: colors.blue[600], + ok: colors.green[800], + error: colors.red[800], + warning: colors.yellow[800], + info: colors.blue[800], }; const iconColor = { @@ -79,63 +78,62 @@ const iconColor = { secondary: colors.neutral[500], muted: colors.neutral[600], placeholder: colors.neutral[700], - active: colors.neutral[50], - //TODO: (design) define feature and it's correct value - feature: colors.sky[500], + active: colors.neutral[900], + feature: colors.sky[600], ok: colors.green[600], - error: colors.red[400], - warning: colors.amber[300], - info: colors.blue[500], + error: colors.red[600], + warning: colors.yellow[400], + info: colors.blue[600], }; const player = { 1: { - baseColor: colors.blue[600], - cursorColor: colors.blue[600], - selectionColor: colors.blue[600], - borderColor: colors.blue[600], + baseColor: colors.blue[600], + cursorColor: colors.blue[500], + selectionColor: colors.blue[100], + borderColor: colors.blue[500], }, 2: { - baseColor: colors.indigo[500], - cursorColor: colors.indigo[500], - selectionColor: colors.indigo[500], - borderColor: colors.indigo[500], + baseColor: colors.indigo[500], + cursorColor: colors.indigo[500], + selectionColor: colors.indigo[100], + borderColor: colors.indigo[500], }, 3: { - baseColor: colors.green[500], - cursorColor: colors.green[500], - selectionColor: colors.green[500], - borderColor: colors.green[500], + baseColor: colors.green[500], + cursorColor: colors.green[500], + selectionColor: colors.green[100], + borderColor: colors.green[500], }, 4: { - baseColor: colors.orange[500], - cursorColor: colors.orange[500], - selectionColor: colors.orange[500], - borderColor: colors.orange[500], + baseColor: colors.orange[500], + cursorColor: colors.orange[500], + selectionColor: colors.orange[100], + borderColor: colors.orange[500], }, 5: { - baseColor: colors.purple[500], - cursorColor: colors.purple[500], - selectionColor: colors.purple[500], - borderColor: colors.purple[500], + baseColor: colors.purple[500], + cursorColor: colors.purple[500], + selectionColor: colors.purple[100], + borderColor: colors.purple[500], }, 6: { - baseColor: colors.teal[400], - cursorColor: colors.teal[400], - selectionColor: colors.teal[400], - borderColor: colors.teal[400], + baseColor: colors.teal[400], + cursorColor: colors.teal[400], + selectionColor: colors.teal[100], + borderColor: colors.teal[400], }, 7: { - baseColor: colors.pink[400], - cursorColor: colors.pink[400], - selectionColor: colors.pink[400], - borderColor: colors.pink[400], + baseColor: colors.pink[400], + cursorColor: colors.pink[400], + selectionColor: colors.pink[100], + borderColor: colors.pink[400], }, 8: { - baseColor: colors.yellow[400], - cursorColor: colors.yellow[400], - selectionColor: colors.yellow[400], - borderColor: colors.yellow[400], + baseColor: colors.yellow[400], + cursorColor: colors.yellow[400], + selectionColor: colors.yellow[100], + borderColor: colors.yellow[400], }, }; @@ -145,118 +143,118 @@ const editor = { indent_guide: borderColor.muted, indent_guide_active: borderColor.secondary, line: { - active: colors.neutral[0], - highlighted: colors.neutral[0], - inserted: backgroundColor.ok.active, - deleted: backgroundColor.error.active, - modified: backgroundColor.info.active, + active: colors.neutral[0], + highlighted: colors.neutral[0], + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, }, highlight: { - selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: colors.neutral[0], - matchingBracket: colors.neutral[0], - match: colors.neutral[0], - activeMatch: colors.neutral[0], - related: colors.neutral[0], + selection: player[1].selectionColor, + occurrence: backgroundColor[500].active, + activeOccurrence: colors.neutral[0], + matchingBracket: colors.neutral[0], + match: colors.neutral[0], + activeMatch: colors.neutral[0], + related: colors.neutral[0], }, gutter: { - primary: colors.neutral[0], - active: colors.neutral[0], + primary: colors.neutral[0], + active: colors.neutral[0], }, }; const syntax: Syntax = { primary: { - color: textColor.primary, - weight: fontWeights.normal, + color: textColor.primary, + weight: fontWeights.normal, }, comment: { - color: colors.lime[200], - weight: fontWeights.normal, + color: colors.lime[200], + weight: fontWeights.normal, }, punctuation: { - color: textColor.primary, - weight: fontWeights.normal, + color: textColor.primary, + weight: fontWeights.normal, }, constant: { - color: colors.neutral[150], - weight: fontWeights.normal, + color: colors.neutral[150], + weight: fontWeights.normal, }, keyword: { - color: colors.sky[400], - weight: fontWeights.normal, + color: colors.sky[400], + weight: fontWeights.normal, }, function: { - color: colors.yellow[200], - weight: fontWeights.normal, + color: colors.yellow[200], + weight: fontWeights.normal, }, type: { - color: colors.teal[300], - weight: fontWeights.normal, + color: colors.teal[300], + weight: fontWeights.normal, }, variant: { - color: colors.teal[300], - weight: fontWeights.normal, + color: colors.teal[300], + weight: fontWeights.normal, }, property: { - color: colors.sky[300], - weight: fontWeights.normal, + color: colors.sky[300], + weight: fontWeights.normal, }, enum: { - color: colors.sky[400], - weight: fontWeights.normal, + color: colors.sky[400], + weight: fontWeights.normal, }, operator: { - color: colors.sky[400], - weight: fontWeights.normal, + color: colors.sky[400], + weight: fontWeights.normal, }, string: { - color: colors.orange[300], - weight: fontWeights.normal, + color: colors.orange[300], + weight: fontWeights.normal, }, number: { - color: colors.neutral[150], - weight: fontWeights.normal, + color: colors.neutral[150], + weight: fontWeights.normal, }, boolean: { - color: colors.neutral[150], - weight: fontWeights.normal, + color: colors.neutral[150], + weight: fontWeights.normal, }, predictive: { - color: textColor.muted, - weight: fontWeights.normal, + color: textColor.muted, + weight: fontWeights.normal, }, title: { - color: colors.sky[500], - weight: fontWeights.bold, + color: colors.sky[500], + weight: fontWeights.bold, }, emphasis: { - color: textColor.active, - weight: fontWeights.normal, + color: textColor.active, + weight: fontWeights.normal, }, emphasisStrong: { - color: textColor.active, - weight: fontWeights.bold, + color: textColor.active, + weight: fontWeights.bold, }, linkUrl: { - color: colors.lime[500], - weight: fontWeights.normal, - // TODO: add underline + color: colors.lime[500], + weight: fontWeights.normal, + // TODO: add underline }, linkText: { - color: colors.orange[500], - weight: fontWeights.normal, - // TODO: add italic + color: colors.orange[500], + weight: fontWeights.normal, + // TODO: add italic }, listMarker: { - color: colors.sky[400], - weight: fontWeights.normal, - } + color: colors.sky[400], + weight: fontWeights.normal, + }, }; const shadowAlpha: NumberToken = { - value: 0.32, + value: 0.12, type: "number", }; diff --git a/styles/themes/theme.ts b/styles/themes/theme.ts index f95d58e49484aea340693ff289f19cb8cf8a4b0a..7f8305c1d539d24fe50f23d650844c0670506dc1 100644 --- a/styles/themes/theme.ts +++ b/styles/themes/theme.ts @@ -1,4 +1,4 @@ -import { FontWeightToken, ColorToken, NumberToken } from "../tokens"; +import { ColorToken, FontWeightToken, NumberToken } from "../tokens"; export interface SyntaxHighlightStyle { color: ColorToken; diff --git a/styles/tokens.ts b/styles/tokens.ts index 1e0df5032d09ee72ce31fc2b9de256174b6bf905..63c19a9d6439a77db5d1d9cd7924966e117a931a 100644 --- a/styles/tokens.ts +++ b/styles/tokens.ts @@ -72,7 +72,7 @@ export interface ColorToken { step?: number, } export const colors = { - neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }), + neutral: colorRamp(["white", "black"], { steps: 19, increment: 50 }), rose: colorRamp("#F43F5EFF"), red: colorRamp("#EF4444FF"), orange: colorRamp("#F97316FF"), From bfde9dca4e0dc1b50f2eb0927efcc6b7985e9dc3 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 1 Apr 2022 23:59:20 -0400 Subject: [PATCH 61/68] Add greg to .zed.toml --- .zed.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zed.toml b/.zed.toml index 0cbe5c59a550cbdae9b8d016123ef315bbd0e18e..fae32125f4f236c7bc99f57f5bf9e6e041984069 100644 --- a/.zed.toml +++ b/.zed.toml @@ -1 +1 @@ -collaborators = ["nathansobo", "as-cii", "maxbrunsfeld", "iamnbutler", "Kethku"] +collaborators = ["nathansobo", "as-cii", "maxbrunsfeld", "iamnbutler", "gibusu", "Kethku"] From c374fd2f548471b587f33ff9d04e21a373cdd1fd Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sat, 2 Apr 2022 01:05:28 -0400 Subject: [PATCH 62/68] WIP --- crates/zed/assets/themes/dark.json | 157 +++++++++--------- crates/zed/assets/themes/light.json | 245 ++++++++++++++-------------- styles/styleTree/app.ts | 3 +- styles/styleTree/editor.ts | 3 +- styles/themes/dark.ts | 54 +++--- styles/themes/light.ts | 38 ++--- styles/utils/color.ts | 4 +- 7 files changed, 251 insertions(+), 253 deletions(-) diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json index fd11fc6c3a64a6fd6d878b935941d21960c12f37..0abf380cc18fc7ecb252d8d062b2ff53aeb4ad7c 100644 --- a/crates/zed/assets/themes/dark.json +++ b/crates/zed/assets/themes/dark.json @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#90df17", + "color": "#72ad19", "weight": "bold", "size": 14 } @@ -33,16 +33,16 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#90df17", + "color": "#72ad19", "weight": "bold", "size": 14 }, - "background": "#000000" + "background": "#1c1c1c" }, "border": { "color": "#0e0e0e", @@ -70,12 +70,12 @@ "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#195cc8", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16 }, "border": { @@ -111,8 +111,8 @@ "background": "#1c1c1c", "icon_close": "#717171", "icon_close_active": "#f1f1f1", - "icon_conflict": "#f7b241", - "icon_dirty": "#4287f6", + "icon_conflict": "#c38214", + "icon_dirty": "#195cc8", "icon_width": 8, "spacing": 10, "text": { @@ -137,8 +137,8 @@ "background": "#000000", "icon_close": "#717171", "icon_close_active": "#f1f1f1", - "icon_conflict": "#f7b241", - "icon_dirty": "#4287f6", + "icon_conflict": "#c38214", + "icon_dirty": "#195cc8", "icon_width": 8, "spacing": 10, "text": { @@ -243,7 +243,7 @@ "share_icon_active_color": "#f1f1f1", "title": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "avatar": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#cc8712", "size": 13 } }, @@ -325,54 +325,54 @@ } }, "editor": { - "text_color": "#9c9c9c", + "text_color": "#e3e3e3", "background": "#000000", - "active_line_background": "#ffffff", + "active_line_background": "#1c1c1c", "code_actions_indicator": "#717171", - "diff_background_deleted": "#f78c8c", - "diff_background_inserted": "#22c55e", - "document_highlight_read_background": "#000000", - "document_highlight_write_background": "#000000", - "error_color": "#f78c8c", + "diff_background_deleted": "#d71c1c", + "diff_background_inserted": "#1ea34f", + "document_highlight_read_background": "#1e22db", + "document_highlight_write_background": "#1e22db", + "error_color": "#d71c1c", "gutter_background": "#000000", "gutter_padding_factor": 2.5, - "highlighted_line_background": "#ffffff", - "line_number": "#ffffff", + "highlighted_line_background": "#0e0e0e", + "line_number": "#636363", "line_number_active": "#ffffff", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#195cc8", + "selection": "#307af3" }, "guest_selections": [ { - "cursor": "#777af4", - "selection": "#777af4" + "cursor": "#70a919", + "selection": "#80c517" }, { - "cursor": "#23d464", - "selection": "#23d464" + "cursor": "#1e22db", + "selection": "#5558ee" }, { - "cursor": "#f98a3d", - "selection": "#f98a3d" + "cursor": "#c45c14", + "selection": "#f66e0f" }, { - "cursor": "#b671f8", - "selection": "#b671f8" + "cursor": "#7d19dc", + "selection": "#a048f4" }, { - "cursor": "#16ddc7", - "selection": "#16ddc7" + "cursor": "#17a293", + "selection": "#15b3a2" }, { - "cursor": "#f58ac0", - "selection": "#f58ac0" + "cursor": "#d51e79", + "selection": "#e93d92" }, { - "cursor": "#f6bc09", - "selection": "#f6bc09" + "cursor": "#bc9212", + "selection": "#e0ac0b" } ], "autocomplete": { @@ -400,13 +400,13 @@ "right": 6, "top": 2 }, - "background": "#000000" + "background": "#0e0e0e" }, "margin": { "left": -14 }, "match_highlight": { - "color": "#59c3f5", + "color": "#1588bc", "weight": "normal" }, "selected_item": { @@ -417,7 +417,7 @@ "right": 6, "top": 2 }, - "background": "#000000" + "background": "#1c1c1c" } }, "diagnostic_header": { @@ -441,7 +441,7 @@ "message": { "highlight_text": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14, "weight": "bold" }, @@ -453,11 +453,11 @@ } }, "diagnostic_path_header": { - "background": "#ffffff", + "background": "#1c1c1c", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "path": { @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#d71c1c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#d71c1c", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#cc8712", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#cc8712", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#185fd0", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#185fd0", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#185fd0", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#185fd0", "size": 14, "weight": "bold" } @@ -656,13 +656,12 @@ "syntax": {} }, "project_diagnostics": { - "background": "#1c1c1c", "tab_icon_spacing": 4, "tab_icon_width": 13, "tab_summary_spacing": 10, "empty_message": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "status_bar_item": { @@ -709,7 +708,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 } }, @@ -721,7 +720,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 } } @@ -735,7 +734,7 @@ }, "channel_name": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "weight": "bold", "size": 14 }, @@ -751,7 +750,7 @@ "header": { "name": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "padding": { @@ -806,7 +805,7 @@ "active_item": { "name": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "padding": 4, @@ -823,7 +822,7 @@ "hovered_active_item": { "name": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14 }, "padding": 4, @@ -864,7 +863,7 @@ }, "hovered_sign_in_prompt": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "underline": true, "size": 14 }, @@ -884,7 +883,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "weight": "bold", "size": 14, "margin": { @@ -921,7 +920,7 @@ "corner_radius": 6, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16 }, "placeholder_text": { @@ -930,8 +929,8 @@ "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#195cc8", + "selection": "#307af3" }, "border": { "color": "#393939", @@ -995,7 +994,7 @@ }, "name": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16, "margin": { "right": 6 @@ -1014,7 +1013,7 @@ }, "name": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16, "margin": { "right": 6 @@ -1023,7 +1022,7 @@ "padding": { "left": 8 }, - "background": "#ffffff", + "background": "#1c1c1c", "corner_radius": 6 }, "unshared_project": { @@ -1063,12 +1062,12 @@ "padding": { "left": 8 }, - "background": "#ffffff", + "background": "#1c1c1c", "corner_radius": 6 } }, "search": { - "match_background": "#ffffff", + "match_background": "#70a919", "tab_icon_spacing": 4, "tab_icon_width": 14, "active_hovered_option_button": { @@ -1124,12 +1123,12 @@ "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#195cc8", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16 }, "border": { @@ -1178,16 +1177,16 @@ "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#4287f6" + "cursor": "#195cc8", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 16 }, "border": { - "color": "#f47171", + "color": "#cd1c1c", "width": 1 }, "margin": { @@ -1235,13 +1234,13 @@ }, "results_status": { "family": "Zed Mono", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 18 } }, "breadcrumbs": { "family": "Zed Sans", - "color": "#d5d5d5", + "color": "#e3e3e3", "size": 14, "padding": { "left": 6 diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json index 219f958e876dcb36abd4edf2e2986c7fb26f32c3..1024764540e55f20505b6864ca6bdddd95881edd 100644 --- a/crates/zed/assets/themes/light.json +++ b/crates/zed/assets/themes/light.json @@ -13,12 +13,12 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#4287f6", + "color": "#185fd0", "weight": "bold", "size": 14 } @@ -33,12 +33,12 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#4287f6", + "color": "#185fd0", "weight": "bold", "size": 14 }, @@ -51,7 +51,7 @@ "empty": { "text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "padding": { @@ -66,16 +66,16 @@ "corner_radius": 6, "placeholder_text": { "family": "Zed Sans", - "color": "#717171", + "color": "#aaaaaa", "size": 14 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#185fd0", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16 }, "border": { @@ -111,13 +111,13 @@ "background": "#f1f1f1", "icon_close": "#717171", "icon_close_active": "#000000", - "icon_conflict": "#f6bc09", - "icon_dirty": "#4287f6", + "icon_conflict": "#bc9212", + "icon_dirty": "#195cc8", "icon_width": 8, "spacing": 10, "text": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 14 }, "border": { @@ -137,8 +137,8 @@ "background": "#ffffff", "icon_close": "#717171", "icon_close_active": "#000000", - "icon_conflict": "#f6bc09", - "icon_dirty": "#4287f6", + "icon_conflict": "#bc9212", + "icon_dirty": "#195cc8", "icon_width": 8, "spacing": 10, "text": { @@ -221,17 +221,17 @@ }, "cursor_position": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "diagnostic_message": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "lsp_message": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 } }, @@ -243,7 +243,7 @@ "share_icon_active_color": "#000000", "title": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "avatar": { @@ -264,7 +264,7 @@ }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 13, "underline": true, "padding": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#b48d14", + "color": "#b68e14", "size": 13 } }, @@ -311,7 +311,7 @@ }, "breadcrumbs": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "padding": { "left": 6 @@ -325,54 +325,54 @@ } }, "editor": { - "text_color": "#393939", + "text_color": "#2b2b2b", "background": "#ffffff", - "active_line_background": "#ffffff", + "active_line_background": "#e3e3e3", "code_actions_indicator": "#717171", - "diff_background_deleted": "#fdd4d4", - "diff_background_inserted": "#befad2", + "diff_background_deleted": "#ec3939", + "diff_background_inserted": "#21bf5b", "document_highlight_read_background": "#e3e3e3", "document_highlight_write_background": "#e3e3e3", - "error_color": "#d11c1c", + "error_color": "#cd1c1c", "gutter_background": "#ffffff", "gutter_padding_factor": 2.5, - "highlighted_line_background": "#ffffff", - "line_number": "#ffffff", - "line_number_active": "#ffffff", + "highlighted_line_background": "#e3e3e3", + "line_number": "#808080", + "line_number_active": "#000000", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#185fd0", + "selection": "#307af3" }, "guest_selections": [ { - "cursor": "#777af4", - "selection": "#d4d5fd" + "cursor": "#70a919", + "selection": "#80c517" }, { - "cursor": "#23d464", - "selection": "#befad2" + "cursor": "#1e22db", + "selection": "#5558ee" }, { - "cursor": "#f98a3d", - "selection": "#fde0cd" + "cursor": "#c45c14", + "selection": "#f66e0f" }, { - "cursor": "#b671f8", - "selection": "#e9d4fd" + "cursor": "#7d19dc", + "selection": "#a048f4" }, { - "cursor": "#16ddc7", - "selection": "#b4faf2" + "cursor": "#17a293", + "selection": "#15b3a2" }, { - "cursor": "#f58ac0", - "selection": "#fcd4e8" + "cursor": "#d51e79", + "selection": "#e93d92" }, { - "cursor": "#f6bc09", - "selection": "#fceabc" + "cursor": "#bc9212", + "selection": "#e0ac0b" } ], "autocomplete": { @@ -406,7 +406,7 @@ "left": -14 }, "match_highlight": { - "color": "#59c3f5", + "color": "#1588bc", "weight": "normal" }, "selected_item": { @@ -432,7 +432,7 @@ }, "code": { "family": "Zed Mono", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "left": 10 @@ -441,28 +441,28 @@ "message": { "highlight_text": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14, "weight": "bold" }, "text": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 14 } } }, "diagnostic_path_header": { - "background": "#ffffff", + "background": "#e3e3e3", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "path": { "family": "Zed Mono", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "left": 12 @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#d11c1c", + "color": "#cd1c1c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#d11c1c", + "color": "#cd1c1c", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#b48d14", + "color": "#b68e14", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#b48d14", + "color": "#b68e14", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#1762db", + "color": "#185fd0", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#1762db", + "color": "#185fd0", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#1762db", + "color": "#185fd0", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#1762db", + "color": "#185fd0", "size": 14, "weight": "bold" } @@ -573,12 +573,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "weight": "bold" } @@ -596,12 +596,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "weight": "bold" } @@ -619,12 +619,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "weight": "bold" } @@ -642,12 +642,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "weight": "bold" } @@ -656,18 +656,17 @@ "syntax": {} }, "project_diagnostics": { - "background": "#f1f1f1", "tab_icon_spacing": 4, "tab_icon_width": 13, "tab_summary_spacing": 10, "empty_message": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "status_bar_item": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 10 @@ -686,7 +685,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 14 } }, @@ -698,7 +697,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 14 } }, @@ -709,7 +708,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 } }, @@ -721,7 +720,7 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 } } @@ -735,13 +734,13 @@ }, "channel_name": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "weight": "bold", "size": 14 }, "channel_name_hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "padding": { "right": 8 @@ -751,7 +750,7 @@ "header": { "name": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "padding": { @@ -760,7 +759,7 @@ }, "hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 8 @@ -771,13 +770,13 @@ "item": { "name": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 8 @@ -788,13 +787,13 @@ "hovered_item": { "name": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 8 @@ -806,13 +805,13 @@ "active_item": { "name": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 8 @@ -823,13 +822,13 @@ "hovered_active_item": { "name": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14 }, "padding": 4, "hash": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14, "margin": { "right": 8 @@ -858,25 +857,25 @@ }, "sign_in_prompt": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "underline": true, "size": 14 }, "hovered_sign_in_prompt": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "underline": true, "size": 14 }, "message": { "body": { "family": "Zed Sans", - "color": "#393939", + "color": "#555555", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "padding": { @@ -884,7 +883,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "weight": "bold", "size": 14, "margin": { @@ -895,12 +894,12 @@ "pending_message": { "body": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "timestamp": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "size": 14 }, "padding": { @@ -908,7 +907,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#555555", + "color": "#808080", "weight": "bold", "size": 14, "margin": { @@ -921,17 +920,17 @@ "corner_radius": 6, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16 }, "placeholder_text": { "family": "Zed Mono", - "color": "#717171", + "color": "#aaaaaa", "size": 14 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#185fd0", + "selection": "#307af3" }, "border": { "color": "#e3e3e3", @@ -961,7 +960,7 @@ }, "host_username": { "family": "Zed Mono", - "color": "#555555", + "color": "#808080", "size": 16, "padding": { "left": 8 @@ -976,7 +975,7 @@ }, "name": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "margin": { "right": 6 @@ -995,7 +994,7 @@ }, "name": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16, "margin": { "right": 6 @@ -1014,7 +1013,7 @@ }, "name": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16, "margin": { "right": 6 @@ -1023,7 +1022,7 @@ "padding": { "left": 8 }, - "background": "#ffffff", + "background": "#e3e3e3", "corner_radius": 6 }, "unshared_project": { @@ -1035,7 +1034,7 @@ }, "name": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "margin": { "right": 6 @@ -1054,7 +1053,7 @@ }, "name": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "margin": { "right": 6 @@ -1063,7 +1062,7 @@ "padding": { "left": 8 }, - "background": "#ffffff", + "background": "#e3e3e3", "corner_radius": 6 } }, @@ -1073,7 +1072,7 @@ "tab_icon_width": 14, "active_hovered_option_button": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "background": "#e3e3e3", "corner_radius": 6, @@ -1094,7 +1093,7 @@ }, "active_option_button": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "background": "#e3e3e3", "corner_radius": 6, @@ -1120,16 +1119,16 @@ "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#717171", + "color": "#aaaaaa", "size": 16 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#185fd0", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16 }, "border": { @@ -1148,7 +1147,7 @@ }, "hovered_option_button": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "background": "#e3e3e3", "corner_radius": 6, @@ -1174,20 +1173,20 @@ "max_width": 500, "placeholder_text": { "family": "Zed Mono", - "color": "#717171", + "color": "#aaaaaa", "size": 16 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#185fd0", + "selection": "#307af3" }, "text": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 16 }, "border": { - "color": "#fbbdbd", + "color": "#e72727", "width": 1 }, "margin": { @@ -1202,13 +1201,13 @@ }, "match_index": { "family": "Zed Mono", - "color": "#555555", + "color": "#808080", "size": 16, "padding": 6 }, "option_button": { "family": "Zed Mono", - "color": "#393939", + "color": "#555555", "size": 16, "background": "#f1f1f1", "corner_radius": 6, @@ -1235,13 +1234,13 @@ }, "results_status": { "family": "Zed Mono", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 18 } }, "breadcrumbs": { "family": "Zed Sans", - "color": "#1c1c1c", + "color": "#2b2b2b", "size": 14, "padding": { "left": 6 diff --git a/styles/styleTree/app.ts b/styles/styleTree/app.ts index d26ada4fc9bc6ebab7c63255245ff003dfae0640..10439b5a0056e8f8ac6ec29e10b4094f1aae26a8 100644 --- a/styles/styleTree/app.ts +++ b/styles/styleTree/app.ts @@ -1,6 +1,6 @@ import Theme from "../themes/theme"; import chatPanel from "./chatPanel"; -import { backgroundColor, borderColor, text } from "./components"; +import { text } from "./components"; import contactsPanel from "./contactsPanel"; import editor from "./editor"; import projectPanel from "./projectPanel"; @@ -18,7 +18,6 @@ export default function app(theme: Theme): Object { workspace: workspace(theme), editor: editor(theme), projectDiagnostics: { - background: backgroundColor(theme, 300), tabIconSpacing: 4, tabIconWidth: 13, tabSummarySpacing: 10, diff --git a/styles/styleTree/editor.ts b/styles/styleTree/editor.ts index eb379ce520bfb5b53b85e5d8e28be639d598a6f9..e760ecec6a57997c48238e0fdeb16d457c2c3e69 100644 --- a/styles/styleTree/editor.ts +++ b/styles/styleTree/editor.ts @@ -38,7 +38,8 @@ export default function editor(theme: Theme) { } return { - textColor: theme.textColor.secondary.value, + // textColor: theme.syntax.primary.color, + textColor: theme.syntax.primary.color.value, background: backgroundColor(theme, 500), activeLineBackground: theme.editor.line.active.value, codeActionsIndicator: iconColor(theme, "secondary"), diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index f8e0c0fcb6b00e157bf577fca2024ca286561c5d..fa05576cd2c3dd191385965c8d5ec9a1ceafc0b7 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -16,9 +16,9 @@ const backgroundColor = { }, 500: { base: colors.neutral[900], - hovered: colors.neutral[900], - active: colors.neutral[900], - focused: colors.neutral[900], + hovered: colors.neutral[850], + active: colors.neutral[800], + focused: colors.neutral[850], }, ok: { base: colors.green[600], @@ -59,7 +59,7 @@ const borderColor = { }; const textColor = { - primary: colors.neutral[150], + primary: colors.neutral[100], secondary: colors.neutral[350], muted: colors.neutral[550], placeholder: colors.neutral[750], @@ -90,49 +90,49 @@ const player = { 1: { baseColor: colors.blue[600], cursorColor: colors.blue[600], - selectionColor: colors.blue[600], + selectionColor: colors.blue[100], borderColor: colors.blue[600], }, 2: { + baseColor: colors.lime[500], + cursorColor: colors.lime[500], + selectionColor: colors.lime[100], + borderColor: colors.lime[500], + }, + 3: { baseColor: colors.indigo[500], cursorColor: colors.indigo[500], - selectionColor: colors.indigo[500], + selectionColor: colors.indigo[100], borderColor: colors.indigo[500], }, - 3: { - baseColor: colors.green[500], - cursorColor: colors.green[500], - selectionColor: colors.green[500], - borderColor: colors.green[500], - }, 4: { baseColor: colors.orange[500], cursorColor: colors.orange[500], - selectionColor: colors.orange[500], + selectionColor: colors.orange[100], borderColor: colors.orange[500], }, 5: { baseColor: colors.purple[500], cursorColor: colors.purple[500], - selectionColor: colors.purple[500], + selectionColor: colors.purple[100], borderColor: colors.purple[500], }, 6: { baseColor: colors.teal[400], cursorColor: colors.teal[400], - selectionColor: colors.teal[400], + selectionColor: colors.teal[100], borderColor: colors.teal[400], }, 7: { baseColor: colors.pink[400], cursorColor: colors.pink[400], - selectionColor: colors.pink[400], + selectionColor: colors.pink[100], borderColor: colors.pink[400], }, 8: { baseColor: colors.yellow[400], cursorColor: colors.yellow[400], - selectionColor: colors.yellow[400], + selectionColor: colors.yellow[100], borderColor: colors.yellow[400], }, }; @@ -143,24 +143,24 @@ const editor = { indent_guide: borderColor.muted, indent_guide_active: borderColor.secondary, line: { - active: colors.neutral[0], - highlighted: colors.neutral[0], + active: backgroundColor[500].active, + highlighted: backgroundColor[500].hovered, inserted: backgroundColor.ok.active, deleted: backgroundColor.error.active, modified: backgroundColor.info.active, }, highlight: { selection: player[1].selectionColor, - occurrence: backgroundColor[500].active, - activeOccurrence: colors.neutral[0], - matchingBracket: colors.neutral[0], - match: colors.neutral[0], - activeMatch: colors.neutral[0], - related: colors.neutral[0], + occurrence: colors.indigo[500], // TODO: Why does indigo[500], indigo[100], and indigo[900] all give me the same color? @kethku + activeOccurrence: colors.indigo[400], // TODO: We don't seem to be using this right now in rust + matchingBracket: backgroundColor[500].active, + match: colors.lime[500], + activeMatch: colors.lime[400], + related: backgroundColor[500].focused, }, gutter: { - primary: colors.neutral[0], - active: colors.neutral[0], + primary: textColor.muted, + active: textColor.active, }, }; diff --git a/styles/themes/light.ts b/styles/themes/light.ts index c543c78a302e3579970998ad1fb23847b1e1f694..ee94e18b19869727eae1c973d908ed3202282c77 100644 --- a/styles/themes/light.ts +++ b/styles/themes/light.ts @@ -61,16 +61,16 @@ const borderColor = { }; const textColor = { - primary: colors.neutral[800], - secondary: colors.neutral[700], - muted: colors.neutral[600], - placeholder: colors.neutral[500], + primary: colors.neutral[750], + secondary: colors.neutral[600], + muted: colors.neutral[450], + placeholder: colors.neutral[300], active: colors.neutral[900], - feature: colors.blue[600], - ok: colors.green[800], - error: colors.red[800], - warning: colors.yellow[800], - info: colors.blue[800], + feature: colors.blue[500], + ok: colors.green[500], + error: colors.red[500], + warning: colors.yellow[500], + info: colors.blue[500], }; const iconColor = { @@ -94,17 +94,17 @@ const player = { borderColor: colors.blue[500], }, 2: { + baseColor: colors.lime[500], + cursorColor: colors.lime[500], + selectionColor: colors.lime[100], + borderColor: colors.lime[500], + }, + 3: { baseColor: colors.indigo[500], cursorColor: colors.indigo[500], selectionColor: colors.indigo[100], borderColor: colors.indigo[500], }, - 3: { - baseColor: colors.green[500], - cursorColor: colors.green[500], - selectionColor: colors.green[100], - borderColor: colors.green[500], - }, 4: { baseColor: colors.orange[500], cursorColor: colors.orange[500], @@ -143,8 +143,8 @@ const editor = { indent_guide: borderColor.muted, indent_guide_active: borderColor.secondary, line: { - active: colors.neutral[0], - highlighted: colors.neutral[0], + active: backgroundColor[500].active, + highlighted: backgroundColor[500].active, inserted: backgroundColor.ok.active, deleted: backgroundColor.error.active, modified: backgroundColor.info.active, @@ -159,8 +159,8 @@ const editor = { related: colors.neutral[0], }, gutter: { - primary: colors.neutral[0], - active: colors.neutral[0], + primary: textColor.muted, + active: textColor.active, }, }; diff --git a/styles/utils/color.ts b/styles/utils/color.ts index b59f4fa69479a1f886229afe1953284f6626f9d8..1042899c737681ddc8e074b19723ed5ba3ad0117 100644 --- a/styles/utils/color.ts +++ b/styles/utils/color.ts @@ -22,8 +22,8 @@ export function colorRamp( .scale([startColor, color, endColor]) .domain([0, 0.5, 1]) .mode("hsl") - .gamma(1) - .correctLightness(true) + .gamma(0.2) + // .correctLightness(true) .padding([0, 0.15]); } From 631d8d034440c3e59410a1e59cf3bf51e0d12a86 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 01:04:34 -0400 Subject: [PATCH 63/68] Refined dark theme styles --- crates/zed/assets/themes/dark.json | 166 ++++++++++++++-------------- crates/zed/assets/themes/light.json | 14 +-- styles/buildThemes.ts | 3 + styles/styleTree/selectorModal.ts | 8 +- styles/styleTree/workspace.ts | 4 +- styles/themes/dark.ts | 38 +++---- styles/tokens.ts | 2 +- styles/utils/color.ts | 2 +- 8 files changed, 120 insertions(+), 117 deletions(-) diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json index 0abf380cc18fc7ecb252d8d062b2ff53aeb4ad7c..25568bf17c9dafaf92beb11be5e4514377f57e76 100644 --- a/crates/zed/assets/themes/dark.json +++ b/crates/zed/assets/themes/dark.json @@ -1,6 +1,6 @@ { "selector": { - "background": "#000000", + "background": "#1c1c1c", "corner_radius": 6, "padding": 8, "item": { @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#72ad19", + "color": "#1684b6", "weight": "bold", "size": 14 } @@ -33,19 +33,19 @@ "corner_radius": 6, "text": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#72ad19", + "color": "#1684b6", "weight": "bold", "size": 14 }, - "background": "#1c1c1c" + "background": "#2b2b2b" }, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "empty": { @@ -62,7 +62,7 @@ } }, "input_editor": { - "background": "#1c1c1c", + "background": "#000000", "corner_radius": 6, "placeholder_text": { "family": "Zed Sans", @@ -75,11 +75,11 @@ }, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16 }, "border": { - "color": "#0e0e0e", + "color": "#151515", "width": 1 }, "padding": { @@ -109,8 +109,8 @@ "tab": { "height": 32, "background": "#1c1c1c", - "icon_close": "#717171", - "icon_close_active": "#f1f1f1", + "icon_close": "#555555", + "icon_close_active": "#ffffff", "icon_conflict": "#c38214", "icon_dirty": "#195cc8", "icon_width": 8, @@ -121,7 +121,7 @@ "size": 14 }, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "left": true, "bottom": true, @@ -135,8 +135,8 @@ "active_tab": { "height": 32, "background": "#000000", - "icon_close": "#717171", - "icon_close_active": "#f1f1f1", + "icon_close": "#555555", + "icon_close_active": "#ffffff", "icon_conflict": "#c38214", "icon_dirty": "#195cc8", "icon_width": 8, @@ -147,7 +147,7 @@ "size": 14 }, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "left": true, "bottom": false, @@ -162,22 +162,22 @@ "width": 30, "background": "#1c1c1c", "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "right": true }, "item": { "height": 32, - "icon_color": "#717171", + "icon_color": "#9c9c9c", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#f1f1f1", + "icon_color": "#ffffff", "icon_size": 18 }, "resize_handle": { - "background": "#0e0e0e", + "background": "#070707", "padding": { "left": 1 } @@ -187,29 +187,29 @@ "width": 30, "background": "#1c1c1c", "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "left": true }, "item": { "height": 32, - "icon_color": "#717171", + "icon_color": "#9c9c9c", "icon_size": 18 }, "active_item": { "height": 32, - "icon_color": "#f1f1f1", + "icon_color": "#ffffff", "icon_size": 18 }, "resize_handle": { - "background": "#0e0e0e", + "background": "#070707", "padding": { "left": 1 } } }, "pane_divider": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "status_bar": { @@ -238,12 +238,12 @@ "titlebar": { "avatar_width": 18, "height": 32, - "background": "#393939", - "share_icon_color": "#717171", - "share_icon_active_color": "#f1f1f1", + "background": "#2b2b2b", + "share_icon_color": "#9c9c9c", + "share_icon_active_color": "#ffffff", "title": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "avatar": { @@ -258,7 +258,7 @@ "width": 12 }, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "bottom": true }, @@ -281,7 +281,7 @@ } }, "offline_icon": { - "color": "#717171", + "color": "#9c9c9c", "width": 16, "padding": { "right": 4 @@ -297,7 +297,7 @@ "height": 34, "background": "#000000", "border": { - "color": "#2b2b2b", + "color": "#070707", "width": 1, "bottom": true }, @@ -325,10 +325,10 @@ } }, "editor": { - "text_color": "#e3e3e3", + "text_color": "#f1f1f1", "background": "#000000", - "active_line_background": "#1c1c1c", - "code_actions_indicator": "#717171", + "active_line_background": "#0e0e0e", + "code_actions_indicator": "#9c9c9c", "diff_background_deleted": "#d71c1c", "diff_background_inserted": "#1ea34f", "document_highlight_read_background": "#1e22db", @@ -336,7 +336,7 @@ "error_color": "#d71c1c", "gutter_background": "#000000", "gutter_padding_factor": 2.5, - "highlighted_line_background": "#0e0e0e", + "highlighted_line_background": "#070707", "line_number": "#636363", "line_number_active": "#ffffff", "rename_fade": 0.6, @@ -380,7 +380,7 @@ "corner_radius": 6, "padding": 6, "border": { - "color": "#393939", + "color": "#151515", "width": 1 }, "item": { @@ -400,7 +400,7 @@ "right": 6, "top": 2 }, - "background": "#0e0e0e" + "background": "#070707" }, "margin": { "left": -14 @@ -417,7 +417,7 @@ "right": 6, "top": 2 }, - "background": "#1c1c1c" + "background": "#0e0e0e" } }, "diagnostic_header": { @@ -425,7 +425,7 @@ "icon_width_factor": 1.5, "text_scale_factor": 0.857, "border": { - "color": "#393939", + "color": "#151515", "width": 1, "bottom": true, "top": true @@ -441,7 +441,7 @@ "message": { "highlight_text": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14, "weight": "bold" }, @@ -453,11 +453,11 @@ } }, "diagnostic_path_header": { - "background": "#1c1c1c", + "background": "#0e0e0e", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "path": { @@ -473,7 +473,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -496,7 +496,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -519,7 +519,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -542,7 +542,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -565,7 +565,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -588,7 +588,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -611,7 +611,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -634,7 +634,7 @@ "text_scale_factor": 0.857, "header": { "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1, "top": true } @@ -661,7 +661,7 @@ "tab_summary_spacing": 10, "empty_message": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "status_bar_item": { @@ -691,7 +691,7 @@ }, "hovered_entry": { "height": 22, - "background": "#1c1c1c", + "background": "#232323", "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, @@ -708,19 +708,19 @@ "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 } }, "hovered_selected_entry": { "height": 22, - "background": "#1c1c1c", + "background": "#232323", "icon_color": "#555555", "icon_size": 8, "icon_spacing": 8, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 } } @@ -734,7 +734,7 @@ }, "channel_name": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "weight": "bold", "size": 14 }, @@ -750,7 +750,7 @@ "header": { "name": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "padding": { @@ -799,13 +799,13 @@ "right": 8 } }, - "background": "#1c1c1c", + "background": "#232323", "corner_radius": 6 }, "active_item": { "name": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "padding": 4, @@ -822,7 +822,7 @@ "hovered_active_item": { "name": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14 }, "padding": 4, @@ -834,7 +834,7 @@ "right": 8 } }, - "background": "#1c1c1c", + "background": "#232323", "corner_radius": 6 }, "menu": { @@ -842,7 +842,7 @@ "corner_radius": 6, "padding": 4, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "shadow": { @@ -863,7 +863,7 @@ }, "hovered_sign_in_prompt": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "underline": true, "size": 14 }, @@ -883,7 +883,7 @@ }, "sender": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "weight": "bold", "size": 14, "margin": { @@ -920,7 +920,7 @@ "corner_radius": 6, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16 }, "placeholder_text": { @@ -933,7 +933,7 @@ "selection": "#307af3" }, "border": { - "color": "#393939", + "color": "#151515", "width": 1 }, "padding": { @@ -952,7 +952,7 @@ "right": 12 }, "host_row_height": 28, - "tree_branch_color": "#2b2b2b", + "tree_branch_color": "#232323", "tree_branch_width": 1, "host_avatar": { "corner_radius": 10, @@ -994,7 +994,7 @@ }, "name": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16, "margin": { "right": 6 @@ -1013,7 +1013,7 @@ }, "name": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16, "margin": { "right": 6 @@ -1022,7 +1022,7 @@ "padding": { "left": 8 }, - "background": "#1c1c1c", + "background": "#0e0e0e", "corner_radius": 6 }, "unshared_project": { @@ -1062,7 +1062,7 @@ "padding": { "left": 8 }, - "background": "#1c1c1c", + "background": "#0e0e0e", "corner_radius": 6 } }, @@ -1074,10 +1074,10 @@ "family": "Zed Mono", "color": "#9c9c9c", "size": 16, - "background": "#393939", + "background": "#2b2b2b", "corner_radius": 6, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "margin": { @@ -1095,10 +1095,10 @@ "family": "Zed Mono", "color": "#9c9c9c", "size": 16, - "background": "#393939", + "background": "#2b2b2b", "corner_radius": 6, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "margin": { @@ -1128,11 +1128,11 @@ }, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16 }, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "margin": { @@ -1149,10 +1149,10 @@ "family": "Zed Mono", "color": "#9c9c9c", "size": 16, - "background": "#393939", + "background": "#2b2b2b", "corner_radius": 6, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "margin": { @@ -1182,7 +1182,7 @@ }, "text": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 16 }, "border": { @@ -1212,7 +1212,7 @@ "background": "#1c1c1c", "corner_radius": 6, "border": { - "color": "#0e0e0e", + "color": "#070707", "width": 1 }, "margin": { @@ -1234,13 +1234,13 @@ }, "results_status": { "family": "Zed Mono", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 18 } }, "breadcrumbs": { "family": "Zed Sans", - "color": "#e3e3e3", + "color": "#f1f1f1", "size": 14, "padding": { "left": 6 diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json index 1024764540e55f20505b6864ca6bdddd95881edd..76fe01501d181cdcbdea018c21357a2c65a728ab 100644 --- a/crates/zed/assets/themes/light.json +++ b/crates/zed/assets/themes/light.json @@ -1,6 +1,6 @@ { "selector": { - "background": "#ffffff", + "background": "#f1f1f1", "corner_radius": 6, "padding": 8, "item": { @@ -42,7 +42,7 @@ "weight": "bold", "size": 14 }, - "background": "#e3e3e3" + "background": "#d5d5d5" }, "border": { "color": "#c6c6c6", @@ -62,7 +62,7 @@ } }, "input_editor": { - "background": "#f1f1f1", + "background": "#ffffff", "corner_radius": 6, "placeholder_text": { "family": "Zed Sans", @@ -79,7 +79,7 @@ "size": 16 }, "border": { - "color": "#c6c6c6", + "color": "#e3e3e3", "width": 1 }, "padding": { @@ -109,7 +109,7 @@ "tab": { "height": 32, "background": "#f1f1f1", - "icon_close": "#717171", + "icon_close": "#555555", "icon_close_active": "#000000", "icon_conflict": "#bc9212", "icon_dirty": "#195cc8", @@ -135,7 +135,7 @@ "active_tab": { "height": 32, "background": "#ffffff", - "icon_close": "#717171", + "icon_close": "#555555", "icon_close_active": "#000000", "icon_conflict": "#bc9212", "icon_dirty": "#195cc8", @@ -297,7 +297,7 @@ "height": 34, "background": "#ffffff", "border": { - "color": "#f1f1f1", + "color": "#c6c6c6", "width": 1, "bottom": true }, diff --git a/styles/buildThemes.ts b/styles/buildThemes.ts index 9128eff45d46a0a11b9a8ddb04013b3b59faf87a..a1a07ecb2d7fa69cdb6d83c8024ec173b1e27127 100644 --- a/styles/buildThemes.ts +++ b/styles/buildThemes.ts @@ -3,6 +3,7 @@ import * as path from "path"; import app from "./styleTree/app"; import dark from "./themes/dark"; import light from "./themes/light"; +import { colors } from "./tokens"; import decamelizeTree from "./utils/decamelizeTree"; const themes = [dark, light]; @@ -14,4 +15,6 @@ for (let theme of themes) { ); fs.writeFileSync(outPath, styleTreeJSON); console.log(`Generated ${outPath}`); + + console.log(JSON.stringify(colors.indigo, null, 2)); } diff --git a/styles/styleTree/selectorModal.ts b/styles/styleTree/selectorModal.ts index fdebe712fa0f1650a3fe4411b4579aa30bb44e2e..47355cff116ff985ac62fd8d1665056422cfcd3c 100644 --- a/styles/styleTree/selectorModal.ts +++ b/styles/styleTree/selectorModal.ts @@ -16,12 +16,12 @@ export default function selectorModal(theme: Theme): Object { const activeItem = { ...item, - background: backgroundColor(theme, 500, "active"), + background: backgroundColor(theme, 300, "active"), text: text(theme, "sans", "primary"), }; return { - background: backgroundColor(theme, 500), + background: backgroundColor(theme, 300), cornerRadius: 6, padding: 8, item, @@ -37,12 +37,12 @@ export default function selectorModal(theme: Theme): Object { }, }, inputEditor: { - background: backgroundColor(theme, 300), + background: backgroundColor(theme, 500), corner_radius: 6, placeholderText: text(theme, "sans", "placeholder"), selection: player(theme, 1).selection, text: text(theme, "mono", "primary"), - border: border(theme, "primary"), + border: border(theme, "secondary"), padding: { bottom: 7, left: 16, diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index a734528d744c21896cb73c090b482615bb3544b3..4349ba0ab6861080a146e6d25b8be9d6af801d71 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -14,7 +14,7 @@ export default function workspace(theme: Theme) { const tab = { height: 32, background: backgroundColor(theme, 300), - iconClose: iconColor(theme, "secondary"), + iconClose: iconColor(theme, "muted"), iconCloseActive: iconColor(theme, "active"), iconConflict: iconColor(theme, "warning"), iconDirty: iconColor(theme, "info"), @@ -135,7 +135,7 @@ export default function workspace(theme: Theme) { toolbar: { height: 34, background: backgroundColor(theme, 500), - border: border(theme, "muted", { bottom: true }), + border: border(theme, "primary", { bottom: true }), itemSpacing: 8, padding: { left: 16, right: 8, top: 4, bottom: 4 }, }, diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index fa05576cd2c3dd191385965c8d5ec9a1ceafc0b7..3cb3b653b4a6407d197049b0baf1ff72997b02c7 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -3,22 +3,22 @@ import Theme, { Syntax } from "./theme"; const backgroundColor = { 100: { - base: colors.neutral[700], - hovered: colors.neutral[700], + base: colors.neutral[750], + hovered: colors.neutral[725], active: colors.neutral[700], - focused: colors.neutral[700], + focused: colors.neutral[675], }, 300: { base: colors.neutral[800], - hovered: colors.neutral[800], - active: colors.neutral[800], - focused: colors.neutral[800], + hovered: colors.neutral[775], + active: colors.neutral[750], + focused: colors.neutral[725], }, 500: { base: colors.neutral[900], - hovered: colors.neutral[850], - active: colors.neutral[800], - focused: colors.neutral[850], + hovered: colors.neutral[875], + active: colors.neutral[850], + focused: colors.neutral[825], }, ok: { base: colors.green[600], @@ -47,11 +47,11 @@ const backgroundColor = { }; const borderColor = { - primary: colors.neutral[850], - secondary: colors.neutral[700], - muted: colors.neutral[750], - focused: colors.neutral[100], - active: colors.neutral[500], + primary: colors.neutral[875], + secondary: colors.neutral[825], + muted: colors.neutral[775], + focused: colors.neutral[500], + active: colors.neutral[900], ok: colors.green[500], error: colors.red[500], warning: colors.amber[500], @@ -59,13 +59,13 @@ const borderColor = { }; const textColor = { - primary: colors.neutral[100], + primary: colors.neutral[50], secondary: colors.neutral[350], muted: colors.neutral[550], placeholder: colors.neutral[750], active: colors.neutral[0], //TODO: (design) define feature and it's correct value - feature: colors.lime[400], + feature: colors.sky[500], ok: colors.green[600], error: colors.red[400], warning: colors.amber[300], @@ -73,11 +73,11 @@ const textColor = { }; const iconColor = { - primary: colors.neutral[300], - secondary: colors.neutral[500], + primary: colors.neutral[200], + secondary: colors.neutral[350], muted: colors.neutral[600], placeholder: colors.neutral[700], - active: colors.neutral[50], + active: colors.neutral[0], //TODO: (design) define feature and it's correct value feature: colors.sky[500], ok: colors.green[600], diff --git a/styles/tokens.ts b/styles/tokens.ts index 63c19a9d6439a77db5d1d9cd7924966e117a931a..aa865ae6943603cda17dbac9f3a4a786cdc45367 100644 --- a/styles/tokens.ts +++ b/styles/tokens.ts @@ -72,7 +72,7 @@ export interface ColorToken { step?: number, } export const colors = { - neutral: colorRamp(["white", "black"], { steps: 19, increment: 50 }), + neutral: colorRamp(["white", "black"], { steps: 37, increment: 25 }), // (900/25) + 1 rose: colorRamp("#F43F5EFF"), red: colorRamp("#EF4444FF"), orange: colorRamp("#F97316FF"), diff --git a/styles/utils/color.ts b/styles/utils/color.ts index 1042899c737681ddc8e074b19723ed5ba3ad0117..c7506f696d4cebd54ebc2045be2b7dc9d14f2c7b 100644 --- a/styles/utils/color.ts +++ b/styles/utils/color.ts @@ -8,7 +8,7 @@ export type ColorRamp = { export function colorRamp( color: Color | [Color, Color], - options?: { steps?: number; increment?: number } + options?: { steps?: number; increment?: number; } ): ColorRamp { let scale: Scale; if (Array.isArray(color)) { From e0e9a145905299a9e0819b46c7e942596b9541c2 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 10:50:41 -0400 Subject: [PATCH 64/68] Remove leftover console.log --- styles/buildThemes.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/styles/buildThemes.ts b/styles/buildThemes.ts index a1a07ecb2d7fa69cdb6d83c8024ec173b1e27127..9128eff45d46a0a11b9a8ddb04013b3b59faf87a 100644 --- a/styles/buildThemes.ts +++ b/styles/buildThemes.ts @@ -3,7 +3,6 @@ import * as path from "path"; import app from "./styleTree/app"; import dark from "./themes/dark"; import light from "./themes/light"; -import { colors } from "./tokens"; import decamelizeTree from "./utils/decamelizeTree"; const themes = [dark, light]; @@ -15,6 +14,4 @@ for (let theme of themes) { ); fs.writeFileSync(outPath, styleTreeJSON); console.log(`Generated ${outPath}`); - - console.log(JSON.stringify(colors.indigo, null, 2)); } From 37441bf3420ddc24fa4b812abd0402d62fbbe564 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 13:30:59 -0400 Subject: [PATCH 65/68] Add basic support for exporting tokens to Figma Tokens. (#724) * WIP on figma token export * WIP Working export * Tidy up the figma tokens script * Correctly format theme json structure for Figma Tokens * Finish up themeTokens imports --- styles/buildFigmaTokens.ts | 99 ++++ styles/figma/core.json | 1155 ++++++++++++++++++++++++++++++++++++ styles/figma/dark.json | 637 ++++++++++++++++++++ styles/figma/light.json | 637 ++++++++++++++++++++ 4 files changed, 2528 insertions(+) create mode 100644 styles/buildFigmaTokens.ts create mode 100644 styles/figma/core.json create mode 100644 styles/figma/dark.json create mode 100644 styles/figma/light.json diff --git a/styles/buildFigmaTokens.ts b/styles/buildFigmaTokens.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b3285e58e24c7f0fefa67a40c512202fdbe4c5b --- /dev/null +++ b/styles/buildFigmaTokens.ts @@ -0,0 +1,99 @@ +import * as fs from "fs"; +import * as path from "path"; +import dark from "./themes/dark"; +import light from "./themes/light"; +import Theme from "./themes/theme"; +import { colors, fontFamilies, fontSizes, fontWeights } from "./tokens"; + +// Organize theme tokens +function themeTokens(theme: Theme): Object { + return { + meta: { + themeName: theme.name, + }, + text: theme.textColor, + icon: theme.iconColor, + background: theme.backgroundColor, + border: theme.borderColor, + editor: theme.editor, + syntax: { + primary: { + value: theme.syntax.primary.color.value, + type: "color", + }, + comment: { + value: theme.syntax.comment.color.value, + type: "color", + }, + keyword: { + value: theme.syntax.keyword.color.value, + type: "color", + }, + function: { + value: theme.syntax.function.color.value, + type: "color", + }, + type: { + value: theme.syntax.type.color.value, + type: "color", + }, + variant: { + value: theme.syntax.variant.color.value, + type: "color", + }, + property: { + value: theme.syntax.property.color.value, + type: "color", + }, + enum: { + value: theme.syntax.enum.color.value, + type: "color", + }, + operator: { + value: theme.syntax.operator.color.value, + type: "color", + }, + string: { + value: theme.syntax.string.color.value, + type: "color", + }, + number: { + value: theme.syntax.number.color.value, + type: "color", + }, + boolean: { + value: theme.syntax.boolean.color.value, + type: "color", + }, + }, + player: theme.player, + shadowAlpha: theme.shadowAlpha, + }; +} + +let themes = [themeTokens(dark), themeTokens(light)]; + +// Create {theme}.json +const themePath = path.resolve(`${__dirname}/figma`); +themes.forEach((theme) => { + const tokenJSON = JSON.stringify(theme, null, 2); + //@ts-ignore //TODO: IDK what the hell TS wants me to do here + fs.writeFileSync(`${themePath}/${theme.meta.themeName}.json`, tokenJSON); +}); + +// Organize core tokens +const coreTokens = { + color: { + ...colors, + }, + text: { + family: fontFamilies, + weight: fontWeights, + }, + size: fontSizes, +}; + +// Create core.json +const corePath = path.resolve(`${__dirname}/figma/core.json`); +const coreTokenJSON = JSON.stringify(coreTokens, null, 2); +fs.writeFileSync(corePath, coreTokenJSON); diff --git a/styles/figma/core.json b/styles/figma/core.json new file mode 100644 index 0000000000000000000000000000000000000000..77dabe6b4e4462acc636427c388d161bb3c54a33 --- /dev/null +++ b/styles/figma/core.json @@ -0,0 +1,1155 @@ +{ + "color": { + "neutral": { + "0": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "25": { + "value": "#f8f8f8", + "step": 25, + "type": "color" + }, + "50": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "75": { + "value": "#eaeaea", + "step": 75, + "type": "color" + }, + "100": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "125": { + "value": "#dcdcdc", + "step": 125, + "type": "color" + }, + "150": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "175": { + "value": "#cdcdcd", + "step": 175, + "type": "color" + }, + "200": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "225": { + "value": "#bfbfbf", + "step": 225, + "type": "color" + }, + "250": { + "value": "#b8b8b8", + "step": 250, + "type": "color" + }, + "275": { + "value": "#b1b1b1", + "step": 275, + "type": "color" + }, + "300": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "325": { + "value": "#a3a3a3", + "step": 325, + "type": "color" + }, + "350": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "375": { + "value": "#959595", + "step": 375, + "type": "color" + }, + "400": { + "value": "#8e8e8e", + "step": 400, + "type": "color" + }, + "425": { + "value": "#878787", + "step": 425, + "type": "color" + }, + "450": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "475": { + "value": "#787878", + "step": 475, + "type": "color" + }, + "500": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "525": { + "value": "#6a6a6a", + "step": 525, + "type": "color" + }, + "550": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "575": { + "value": "#5c5c5c", + "step": 575, + "type": "color" + }, + "600": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "625": { + "value": "#4e4e4e", + "step": 625, + "type": "color" + }, + "650": { + "value": "#474747", + "step": 650, + "type": "color" + }, + "675": { + "value": "#404040", + "step": 675, + "type": "color" + }, + "700": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "725": { + "value": "#323232", + "step": 725, + "type": "color" + }, + "750": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "775": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "800": { + "value": "#1c1c1c", + "step": 800, + "type": "color" + }, + "825": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "850": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "875": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "900": { + "value": "#000000", + "step": 900, + "type": "color" + } + }, + "rose": { + "0": { + "value": "#feecef", + "step": 0, + "type": "color" + }, + "100": { + "value": "#f13455", + "step": 100, + "type": "color" + }, + "200": { + "value": "#eb2245", + "step": 200, + "type": "color" + }, + "300": { + "value": "#e7183b", + "step": 300, + "type": "color" + }, + "400": { + "value": "#da193a", + "step": 400, + "type": "color" + }, + "500": { + "value": "#d01939", + "step": 500, + "type": "color" + }, + "600": { + "value": "#c81a37", + "step": 600, + "type": "color" + }, + "700": { + "value": "#c01a36", + "step": 700, + "type": "color" + }, + "800": { + "value": "#ba1a36", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b41a35", + "step": 900, + "type": "color" + } + }, + "red": { + "0": { + "value": "#feecec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#ec3939", + "step": 100, + "type": "color" + }, + "200": { + "value": "#e72727", + "step": 200, + "type": "color" + }, + "300": { + "value": "#e31c1c", + "step": 300, + "type": "color" + }, + "400": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "500": { + "value": "#cd1c1c", + "step": 500, + "type": "color" + }, + "600": { + "value": "#c51c1c", + "step": 600, + "type": "color" + }, + "700": { + "value": "#be1c1c", + "step": 700, + "type": "color" + }, + "800": { + "value": "#b81c1c", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b21c1c", + "step": 900, + "type": "color" + } + }, + "orange": { + "0": { + "value": "#fef3ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#f66e0f", + "step": 100, + "type": "color" + }, + "200": { + "value": "#e5660f", + "step": 200, + "type": "color" + }, + "300": { + "value": "#d66211", + "step": 300, + "type": "color" + }, + "400": { + "value": "#cc5f13", + "step": 400, + "type": "color" + }, + "500": { + "value": "#c45c14", + "step": 500, + "type": "color" + }, + "600": { + "value": "#bc5a15", + "step": 600, + "type": "color" + }, + "700": { + "value": "#b65816", + "step": 700, + "type": "color" + }, + "800": { + "value": "#b15617", + "step": 800, + "type": "color" + }, + "900": { + "value": "#ac5517", + "step": 900, + "type": "color" + } + }, + "amber": { + "0": { + "value": "#fef7ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#eb980d", + "step": 100, + "type": "color" + }, + "200": { + "value": "#d88e10", + "step": 200, + "type": "color" + }, + "300": { + "value": "#cc8712", + "step": 300, + "type": "color" + }, + "400": { + "value": "#c38214", + "step": 400, + "type": "color" + }, + "500": { + "value": "#bb7e15", + "step": 500, + "type": "color" + }, + "600": { + "value": "#b57a16", + "step": 600, + "type": "color" + }, + "700": { + "value": "#b07717", + "step": 700, + "type": "color" + }, + "800": { + "value": "#ab7517", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a77218", + "step": 900, + "type": "color" + } + }, + "yellow": { + "0": { + "value": "#fef9ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "200": { + "value": "#cfa00f", + "step": 200, + "type": "color" + }, + "300": { + "value": "#c49811", + "step": 300, + "type": "color" + }, + "400": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "500": { + "value": "#b68e14", + "step": 500, + "type": "color" + }, + "600": { + "value": "#b08a15", + "step": 600, + "type": "color" + }, + "700": { + "value": "#ac8615", + "step": 700, + "type": "color" + }, + "800": { + "value": "#a88316", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a48117", + "step": 900, + "type": "color" + } + }, + "lime": { + "0": { + "value": "#f7feec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#80c517", + "step": 100, + "type": "color" + }, + "200": { + "value": "#7aba18", + "step": 200, + "type": "color" + }, + "300": { + "value": "#76b318", + "step": 300, + "type": "color" + }, + "400": { + "value": "#72ad19", + "step": 400, + "type": "color" + }, + "500": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "600": { + "value": "#6ea519", + "step": 600, + "type": "color" + }, + "700": { + "value": "#6ca219", + "step": 700, + "type": "color" + }, + "800": { + "value": "#6a9f1a", + "step": 800, + "type": "color" + }, + "900": { + "value": "#699c1a", + "step": 900, + "type": "color" + } + }, + "green": { + "0": { + "value": "#ecfef2", + "step": 0, + "type": "color" + }, + "100": { + "value": "#21bf5b", + "step": 100, + "type": "color" + }, + "200": { + "value": "#20b557", + "step": 200, + "type": "color" + }, + "300": { + "value": "#1faf54", + "step": 300, + "type": "color" + }, + "400": { + "value": "#1faa52", + "step": 400, + "type": "color" + }, + "500": { + "value": "#1ea650", + "step": 500, + "type": "color" + }, + "600": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "700": { + "value": "#1da04d", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1d9d4c", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1d9b4b", + "step": 900, + "type": "color" + } + }, + "emerald": { + "0": { + "value": "#ecfef8", + "step": 0, + "type": "color" + }, + "100": { + "value": "#11b47e", + "step": 100, + "type": "color" + }, + "200": { + "value": "#13ac79", + "step": 200, + "type": "color" + }, + "300": { + "value": "#14a776", + "step": 300, + "type": "color" + }, + "400": { + "value": "#15a374", + "step": 400, + "type": "color" + }, + "500": { + "value": "#16a072", + "step": 500, + "type": "color" + }, + "600": { + "value": "#169d70", + "step": 600, + "type": "color" + }, + "700": { + "value": "#179b6f", + "step": 700, + "type": "color" + }, + "800": { + "value": "#17996e", + "step": 800, + "type": "color" + }, + "900": { + "value": "#18976c", + "step": 900, + "type": "color" + } + }, + "teal": { + "0": { + "value": "#ecfefc", + "step": 0, + "type": "color" + }, + "100": { + "value": "#15b3a2", + "step": 100, + "type": "color" + }, + "200": { + "value": "#16ab9b", + "step": 200, + "type": "color" + }, + "300": { + "value": "#17a696", + "step": 300, + "type": "color" + }, + "400": { + "value": "#17a293", + "step": 400, + "type": "color" + }, + "500": { + "value": "#189f90", + "step": 500, + "type": "color" + }, + "600": { + "value": "#189d8e", + "step": 600, + "type": "color" + }, + "700": { + "value": "#189a8c", + "step": 700, + "type": "color" + }, + "800": { + "value": "#19988a", + "step": 800, + "type": "color" + }, + "900": { + "value": "#199788", + "step": 900, + "type": "color" + } + }, + "cyan": { + "0": { + "value": "#ecfcfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#09b5cc", + "step": 100, + "type": "color" + }, + "200": { + "value": "#0daabf", + "step": 200, + "type": "color" + }, + "300": { + "value": "#0fa3b7", + "step": 300, + "type": "color" + }, + "400": { + "value": "#119eb1", + "step": 400, + "type": "color" + }, + "500": { + "value": "#1299ac", + "step": 500, + "type": "color" + }, + "600": { + "value": "#1396a8", + "step": 600, + "type": "color" + }, + "700": { + "value": "#1493a4", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1590a1", + "step": 800, + "type": "color" + }, + "900": { + "value": "#168e9e", + "step": 900, + "type": "color" + } + }, + "sky": { + "0": { + "value": "#ecf8fe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#109fdf", + "step": 100, + "type": "color" + }, + "200": { + "value": "#1394cf", + "step": 200, + "type": "color" + }, + "300": { + "value": "#148dc4", + "step": 300, + "type": "color" + }, + "400": { + "value": "#1588bc", + "step": 400, + "type": "color" + }, + "500": { + "value": "#1684b6", + "step": 500, + "type": "color" + }, + "600": { + "value": "#1780b0", + "step": 600, + "type": "color" + }, + "700": { + "value": "#177dac", + "step": 700, + "type": "color" + }, + "800": { + "value": "#187ba8", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1878a4", + "step": 900, + "type": "color" + } + }, + "blue": { + "0": { + "value": "#ecf3fe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "200": { + "value": "#1f6eed", + "step": 200, + "type": "color" + }, + "300": { + "value": "#1666e7", + "step": 300, + "type": "color" + }, + "400": { + "value": "#1762db", + "step": 400, + "type": "color" + }, + "500": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "600": { + "value": "#195cc8", + "step": 600, + "type": "color" + }, + "700": { + "value": "#1959c0", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1957ba", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1a55b4", + "step": 900, + "type": "color" + } + }, + "indigo": { + "0": { + "value": "#ececfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#5558ee", + "step": 100, + "type": "color" + }, + "200": { + "value": "#3d41e9", + "step": 200, + "type": "color" + }, + "300": { + "value": "#2e32e5", + "step": 300, + "type": "color" + }, + "400": { + "value": "#2327e2", + "step": 400, + "type": "color" + }, + "500": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "600": { + "value": "#1e22d1", + "step": 600, + "type": "color" + }, + "700": { + "value": "#1e21c9", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1e21c1", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1d20bb", + "step": 900, + "type": "color" + } + }, + "violet": { + "0": { + "value": "#f1ecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#804ef3", + "step": 100, + "type": "color" + }, + "200": { + "value": "#6e37ee", + "step": 200, + "type": "color" + }, + "300": { + "value": "#6329e9", + "step": 300, + "type": "color" + }, + "400": { + "value": "#5a1ee6", + "step": 400, + "type": "color" + }, + "500": { + "value": "#551bde", + "step": 500, + "type": "color" + }, + "600": { + "value": "#531bd4", + "step": 600, + "type": "color" + }, + "700": { + "value": "#501bcb", + "step": 700, + "type": "color" + }, + "800": { + "value": "#4e1bc3", + "step": 800, + "type": "color" + }, + "900": { + "value": "#4c1bbc", + "step": 900, + "type": "color" + } + }, + "purple": { + "0": { + "value": "#f5ecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#a048f4", + "step": 100, + "type": "color" + }, + "200": { + "value": "#9332ee", + "step": 200, + "type": "color" + }, + "300": { + "value": "#8a24ea", + "step": 300, + "type": "color" + }, + "400": { + "value": "#831ae7", + "step": 400, + "type": "color" + }, + "500": { + "value": "#7d19dc", + "step": 500, + "type": "color" + }, + "600": { + "value": "#781ad2", + "step": 600, + "type": "color" + }, + "700": { + "value": "#741ac9", + "step": 700, + "type": "color" + }, + "800": { + "value": "#701bc2", + "step": 800, + "type": "color" + }, + "900": { + "value": "#6d1bbb", + "step": 900, + "type": "color" + } + }, + "fuschia": { + "0": { + "value": "#fdecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#d63be2", + "step": 100, + "type": "color" + }, + "200": { + "value": "#d12ade", + "step": 200, + "type": "color" + }, + "300": { + "value": "#ca23d6", + "step": 300, + "type": "color" + }, + "400": { + "value": "#c122cc", + "step": 400, + "type": "color" + }, + "500": { + "value": "#b921c4", + "step": 500, + "type": "color" + }, + "600": { + "value": "#b320bd", + "step": 600, + "type": "color" + }, + "700": { + "value": "#ad20b7", + "step": 700, + "type": "color" + }, + "800": { + "value": "#a81fb2", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a41ead", + "step": 900, + "type": "color" + } + }, + "pink": { + "0": { + "value": "#feecf5", + "step": 0, + "type": "color" + }, + "100": { + "value": "#e93d92", + "step": 100, + "type": "color" + }, + "200": { + "value": "#e42a87", + "step": 200, + "type": "color" + }, + "300": { + "value": "#e11e7f", + "step": 300, + "type": "color" + }, + "400": { + "value": "#d51e79", + "step": 400, + "type": "color" + }, + "500": { + "value": "#cc1e75", + "step": 500, + "type": "color" + }, + "600": { + "value": "#c41e71", + "step": 600, + "type": "color" + }, + "700": { + "value": "#bd1d6d", + "step": 700, + "type": "color" + }, + "800": { + "value": "#b71d6a", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b21d67", + "step": 900, + "type": "color" + } + } + }, + "text": { + "family": { + "sans": { + "value": "Zed Sans", + "type": "fontFamily" + }, + "mono": { + "value": "Zed Mono", + "type": "fontFamily" + } + }, + "weight": { + "thin": { + "value": "thin", + "type": "fontWeight" + }, + "extra_light": { + "value": "extra_light", + "type": "fontWeight" + }, + "light": { + "value": "light", + "type": "fontWeight" + }, + "normal": { + "value": "normal", + "type": "fontWeight" + }, + "medium": { + "value": "medium", + "type": "fontWeight" + }, + "semibold": { + "value": "semibold", + "type": "fontWeight" + }, + "bold": { + "value": "bold", + "type": "fontWeight" + }, + "extra_bold": { + "value": "extra_bold", + "type": "fontWeight" + }, + "black": { + "value": "black", + "type": "fontWeight" + } + } + }, + "size": { + "3xs": { + "value": 8, + "type": "fontSize" + }, + "2xs": { + "value": 10, + "type": "fontSize" + }, + "xs": { + "value": 12, + "type": "fontSize" + }, + "sm": { + "value": 14, + "type": "fontSize" + }, + "md": { + "value": 16, + "type": "fontSize" + }, + "lg": { + "value": 18, + "type": "fontSize" + }, + "xl": { + "value": 20, + "type": "fontSize" + } + } +} \ No newline at end of file diff --git a/styles/figma/dark.json b/styles/figma/dark.json new file mode 100644 index 0000000000000000000000000000000000000000..fadaf7c19e3459fb3b20cd9af5fc930a2231f010 --- /dev/null +++ b/styles/figma/dark.json @@ -0,0 +1,637 @@ +{ + "meta": { + "themeName": "dark" + }, + "text": { + "primary": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "secondary": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "muted": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "placeholder": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "feature": { + "value": "#1684b6", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "error": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "warning": { + "value": "#cc8712", + "step": 300, + "type": "color" + }, + "info": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "secondary": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "muted": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "placeholder": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "feature": { + "value": "#1684b6", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "error": { + "value": "#cd1c1c", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#c38214", + "step": 400, + "type": "color" + }, + "info": { + "value": "#195cc8", + "step": 600, + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "hovered": { + "value": "#323232", + "step": 725, + "type": "color" + }, + "active": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "focused": { + "value": "#404040", + "step": 675, + "type": "color" + } + }, + "300": { + "base": { + "value": "#1c1c1c", + "step": 800, + "type": "color" + }, + "hovered": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "active": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "focused": { + "value": "#323232", + "step": 725, + "type": "color" + } + }, + "500": { + "base": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "hovered": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "active": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "focused": { + "value": "#151515", + "step": 825, + "type": "color" + } + }, + "ok": { + "base": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "hovered": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "active": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "focused": { + "value": "#1ea34f", + "step": 600, + "type": "color" + } + }, + "error": { + "base": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "hovered": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "active": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "focused": { + "value": "#d71c1c", + "step": 400, + "type": "color" + } + }, + "warning": { + "base": { + "value": "#cc8712", + "step": 300, + "type": "color" + }, + "hovered": { + "value": "#cc8712", + "step": 300, + "type": "color" + }, + "active": { + "value": "#cc8712", + "step": 300, + "type": "color" + }, + "focused": { + "value": "#cc8712", + "step": 300, + "type": "color" + } + }, + "info": { + "base": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "hovered": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "active": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "focused": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "secondary": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "muted": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "focused": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "ok": { + "value": "#1ea650", + "step": 500, + "type": "color" + }, + "error": { + "value": "#cd1c1c", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#bb7e15", + "step": 500, + "type": "color" + }, + "info": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + }, + "editor": { + "background": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "indent_guide": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "indent_guide_active": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "line": { + "active": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "highlighted": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "inserted": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "deleted": { + "value": "#d71c1c", + "step": 400, + "type": "color" + }, + "modified": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "occurrence": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "activeOccurrence": { + "value": "#2327e2", + "step": 400, + "type": "color" + }, + "matchingBracket": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "match": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "activeMatch": { + "value": "#72ad19", + "step": 400, + "type": "color" + }, + "related": { + "value": "#151515", + "step": 825, + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#f1f1f1", + "type": "color" + }, + "comment": { + "value": "#7aba18", + "type": "color" + }, + "keyword": { + "value": "#1588bc", + "type": "color" + }, + "function": { + "value": "#cfa00f", + "type": "color" + }, + "type": { + "value": "#17a696", + "type": "color" + }, + "variant": { + "value": "#17a696", + "type": "color" + }, + "property": { + "value": "#148dc4", + "type": "color" + }, + "enum": { + "value": "#1588bc", + "type": "color" + }, + "operator": { + "value": "#1588bc", + "type": "color" + }, + "string": { + "value": "#d66211", + "type": "color" + }, + "number": { + "value": "#d5d5d5", + "type": "color" + }, + "boolean": { + "value": "#d5d5d5", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#195cc8", + "step": 600, + "type": "color" + }, + "cursorColor": { + "value": "#195cc8", + "step": 600, + "type": "color" + }, + "selectionColor": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#195cc8", + "step": 600, + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#80c517", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#70a919", + "step": 500, + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#5558ee", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#f66e0f", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#a048f4", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#17a293", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#17a293", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#15b3a2", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#17a293", + "step": 400, + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#e93d92", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.32, + "type": "number" + } +} \ No newline at end of file diff --git a/styles/figma/light.json b/styles/figma/light.json new file mode 100644 index 0000000000000000000000000000000000000000..415ab40933c5be2c343b8174c95c9e9917e76675 --- /dev/null +++ b/styles/figma/light.json @@ -0,0 +1,637 @@ +{ + "meta": { + "themeName": "light" + }, + "text": { + "primary": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "secondary": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "muted": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "placeholder": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "feature": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#1ea650", + "step": 500, + "type": "color" + }, + "error": { + "value": "#cd1c1c", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#b68e14", + "step": 500, + "type": "color" + }, + "info": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "secondary": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "muted": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "placeholder": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "feature": { + "value": "#1780b0", + "step": 600, + "type": "color" + }, + "ok": { + "value": "#1ea34f", + "step": 600, + "type": "color" + }, + "error": { + "value": "#c51c1c", + "step": 600, + "type": "color" + }, + "warning": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "info": { + "value": "#195cc8", + "step": 600, + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "active": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "focused": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + } + }, + "300": { + "base": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "hovered": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "active": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "focused": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + } + }, + "500": { + "base": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "hovered": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + } + }, + "ok": { + "base": { + "value": "#21bf5b", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#21bf5b", + "step": 100, + "type": "color" + }, + "active": { + "value": "#21bf5b", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#21bf5b", + "step": 100, + "type": "color" + } + }, + "error": { + "base": { + "value": "#ec3939", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#ec3939", + "step": 100, + "type": "color" + }, + "active": { + "value": "#ec3939", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#ec3939", + "step": 100, + "type": "color" + } + }, + "warning": { + "base": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "active": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + } + }, + "info": { + "base": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "active": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#307af3", + "step": 100, + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "secondary": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "muted": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "focused": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "active": { + "value": "#b8b8b8", + "step": 250, + "type": "color" + }, + "ok": { + "value": "#20b557", + "step": 200, + "type": "color" + }, + "error": { + "value": "#e72727", + "step": 200, + "type": "color" + }, + "warning": { + "value": "#cfa00f", + "step": 200, + "type": "color" + }, + "info": { + "value": "#1f6eed", + "step": 200, + "type": "color" + } + }, + "editor": { + "background": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "indent_guide": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "indent_guide_active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "line": { + "active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "highlighted": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "inserted": { + "value": "#21bf5b", + "step": 100, + "type": "color" + }, + "deleted": { + "value": "#ec3939", + "step": 100, + "type": "color" + }, + "modified": { + "value": "#307af3", + "step": 100, + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "occurrence": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "activeOccurrence": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "matchingBracket": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "match": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "activeMatch": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "related": { + "value": "#ffffff", + "step": 0, + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#2b2b2b", + "type": "color" + }, + "comment": { + "value": "#7aba18", + "type": "color" + }, + "keyword": { + "value": "#1588bc", + "type": "color" + }, + "function": { + "value": "#cfa00f", + "type": "color" + }, + "type": { + "value": "#17a696", + "type": "color" + }, + "variant": { + "value": "#17a696", + "type": "color" + }, + "property": { + "value": "#148dc4", + "type": "color" + }, + "enum": { + "value": "#1588bc", + "type": "color" + }, + "operator": { + "value": "#1588bc", + "type": "color" + }, + "string": { + "value": "#d66211", + "type": "color" + }, + "number": { + "value": "#d5d5d5", + "type": "color" + }, + "boolean": { + "value": "#d5d5d5", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#195cc8", + "step": 600, + "type": "color" + }, + "cursorColor": { + "value": "#185fd0", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#307af3", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#185fd0", + "step": 500, + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#70a919", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#80c517", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#70a919", + "step": 500, + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#5558ee", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#1e22db", + "step": 500, + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#f66e0f", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#c45c14", + "step": 500, + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#a048f4", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#7d19dc", + "step": 500, + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#17a293", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#17a293", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#15b3a2", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#17a293", + "step": 400, + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#e93d92", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#d51e79", + "step": 400, + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#e0ac0b", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#bc9212", + "step": 400, + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.12, + "type": "number" + } +} \ No newline at end of file From 90df8a31e77c02e81bc55f45ba676a65e4c42f02 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 13:37:47 -0400 Subject: [PATCH 66/68] Fix incorrect ramp preset values in `color.ts` - Regenerate themes and tokens as well --- crates/zed/assets/themes/dark.json | 94 +++++----- crates/zed/assets/themes/light.json | 88 ++++----- styles/figma/core.json | 272 ++++++++++++++-------------- styles/figma/dark.json | 158 ++++++++-------- styles/figma/light.json | 150 +++++++-------- styles/utils/color.ts | 4 +- 6 files changed, 383 insertions(+), 383 deletions(-) diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json index 25568bf17c9dafaf92beb11be5e4514377f57e76..da7fa4650ee609d46ce2eacf5dcf8eb4a3f8088c 100644 --- a/crates/zed/assets/themes/dark.json +++ b/crates/zed/assets/themes/dark.json @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#1684b6", + "color": "#2db4f3", "weight": "bold", "size": 14 } @@ -38,7 +38,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#1684b6", + "color": "#2db4f3", "weight": "bold", "size": 14 }, @@ -70,8 +70,8 @@ "size": 14 }, "selection": { - "cursor": "#195cc8", - "selection": "#307af3" + "cursor": "#4287f6", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -111,8 +111,8 @@ "background": "#1c1c1c", "icon_close": "#555555", "icon_close_active": "#ffffff", - "icon_conflict": "#c38214", - "icon_dirty": "#195cc8", + "icon_conflict": "#f7b241", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { @@ -137,8 +137,8 @@ "background": "#000000", "icon_close": "#555555", "icon_close_active": "#ffffff", - "icon_conflict": "#c38214", - "icon_dirty": "#195cc8", + "icon_conflict": "#f7b241", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#cc8712", + "color": "#f8c570", "size": 13 } }, @@ -329,11 +329,11 @@ "background": "#000000", "active_line_background": "#0e0e0e", "code_actions_indicator": "#9c9c9c", - "diff_background_deleted": "#d71c1c", - "diff_background_inserted": "#1ea34f", - "document_highlight_read_background": "#1e22db", - "document_highlight_write_background": "#1e22db", - "error_color": "#d71c1c", + "diff_background_deleted": "#f78c8c", + "diff_background_inserted": "#22c55e", + "document_highlight_read_background": "#777af4", + "document_highlight_write_background": "#777af4", + "error_color": "#f78c8c", "gutter_background": "#000000", "gutter_padding_factor": 2.5, "highlighted_line_background": "#070707", @@ -342,37 +342,37 @@ "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#195cc8", - "selection": "#307af3" + "cursor": "#4287f6", + "selection": "#d0e2fd" }, "guest_selections": [ { - "cursor": "#70a919", - "selection": "#80c517" + "cursor": "#87d116", + "selection": "#dbf9ac" }, { - "cursor": "#1e22db", - "selection": "#5558ee" + "cursor": "#777af4", + "selection": "#d4d5fd" }, { - "cursor": "#c45c14", - "selection": "#f66e0f" + "cursor": "#f98a3d", + "selection": "#fde0cd" }, { - "cursor": "#7d19dc", - "selection": "#a048f4" + "cursor": "#b671f8", + "selection": "#e9d4fd" }, { - "cursor": "#17a293", - "selection": "#15b3a2" + "cursor": "#16ddc7", + "selection": "#b4faf2" }, { - "cursor": "#d51e79", - "selection": "#e93d92" + "cursor": "#f58ac0", + "selection": "#fcd4e8" }, { - "cursor": "#bc9212", - "selection": "#e0ac0b" + "cursor": "#f6bc09", + "selection": "#fceabc" } ], "autocomplete": { @@ -406,7 +406,7 @@ "left": -14 }, "match_highlight": { - "color": "#1588bc", + "color": "#59c3f5", "weight": "normal" }, "selected_item": { @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#d71c1c", + "color": "#f78c8c", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#d71c1c", + "color": "#f78c8c", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#cc8712", + "color": "#f8c570", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#cc8712", + "color": "#f8c570", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14, "weight": "bold" } @@ -929,8 +929,8 @@ "size": 14 }, "selection": { - "cursor": "#195cc8", - "selection": "#307af3" + "cursor": "#4287f6", + "selection": "#d0e2fd" }, "border": { "color": "#151515", @@ -1067,7 +1067,7 @@ } }, "search": { - "match_background": "#70a919", + "match_background": "#87d116", "tab_icon_spacing": 4, "tab_icon_width": 14, "active_hovered_option_button": { @@ -1123,8 +1123,8 @@ "size": 16 }, "selection": { - "cursor": "#195cc8", - "selection": "#307af3" + "cursor": "#4287f6", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -1177,8 +1177,8 @@ "size": 16 }, "selection": { - "cursor": "#195cc8", - "selection": "#307af3" + "cursor": "#4287f6", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -1186,7 +1186,7 @@ "size": 16 }, "border": { - "color": "#cd1c1c", + "color": "#f47171", "width": 1 }, "margin": { diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json index 76fe01501d181cdcbdea018c21357a2c65a728ab..dcff3352f75703a64030db29cde7797dd038c432 100644 --- a/crates/zed/assets/themes/light.json +++ b/crates/zed/assets/themes/light.json @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "weight": "bold", "size": 14 } @@ -38,7 +38,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "weight": "bold", "size": 14 }, @@ -70,8 +70,8 @@ "size": 14 }, "selection": { - "cursor": "#185fd0", - "selection": "#307af3" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -111,8 +111,8 @@ "background": "#f1f1f1", "icon_close": "#555555", "icon_close_active": "#000000", - "icon_conflict": "#bc9212", - "icon_dirty": "#195cc8", + "icon_conflict": "#f6bc09", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { @@ -137,8 +137,8 @@ "background": "#ffffff", "icon_close": "#555555", "icon_close_active": "#000000", - "icon_conflict": "#bc9212", - "icon_dirty": "#195cc8", + "icon_conflict": "#f6bc09", + "icon_dirty": "#4287f6", "icon_width": 8, "spacing": 10, "text": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#b68e14", + "color": "#e5af09", "size": 13 } }, @@ -329,11 +329,11 @@ "background": "#ffffff", "active_line_background": "#e3e3e3", "code_actions_indicator": "#717171", - "diff_background_deleted": "#ec3939", - "diff_background_inserted": "#21bf5b", + "diff_background_deleted": "#fdd4d4", + "diff_background_inserted": "#befad2", "document_highlight_read_background": "#e3e3e3", "document_highlight_write_background": "#e3e3e3", - "error_color": "#cd1c1c", + "error_color": "#f47171", "gutter_background": "#ffffff", "gutter_padding_factor": 2.5, "highlighted_line_background": "#e3e3e3", @@ -342,37 +342,37 @@ "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#185fd0", - "selection": "#307af3" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "guest_selections": [ { - "cursor": "#70a919", - "selection": "#80c517" + "cursor": "#87d116", + "selection": "#dbf9ac" }, { - "cursor": "#1e22db", - "selection": "#5558ee" + "cursor": "#777af4", + "selection": "#d4d5fd" }, { - "cursor": "#c45c14", - "selection": "#f66e0f" + "cursor": "#f98a3d", + "selection": "#fde0cd" }, { - "cursor": "#7d19dc", - "selection": "#a048f4" + "cursor": "#b671f8", + "selection": "#e9d4fd" }, { - "cursor": "#17a293", - "selection": "#15b3a2" + "cursor": "#16ddc7", + "selection": "#b4faf2" }, { - "cursor": "#d51e79", - "selection": "#e93d92" + "cursor": "#f58ac0", + "selection": "#fcd4e8" }, { - "cursor": "#bc9212", - "selection": "#e0ac0b" + "cursor": "#f6bc09", + "selection": "#fceabc" } ], "autocomplete": { @@ -406,7 +406,7 @@ "left": -14 }, "match_highlight": { - "color": "#1588bc", + "color": "#59c3f5", "weight": "normal" }, "selected_item": { @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#cd1c1c", + "color": "#f47171", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#cd1c1c", + "color": "#f47171", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#b68e14", + "color": "#e5af09", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#b68e14", + "color": "#e5af09", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#185fd0", + "color": "#6099f7", "size": 14, "weight": "bold" } @@ -929,8 +929,8 @@ "size": 14 }, "selection": { - "cursor": "#185fd0", - "selection": "#307af3" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "border": { "color": "#e3e3e3", @@ -1123,8 +1123,8 @@ "size": 16 }, "selection": { - "cursor": "#185fd0", - "selection": "#307af3" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -1177,8 +1177,8 @@ "size": 16 }, "selection": { - "cursor": "#185fd0", - "selection": "#307af3" + "cursor": "#6099f7", + "selection": "#d0e2fd" }, "text": { "family": "Zed Mono", @@ -1186,7 +1186,7 @@ "size": 16 }, "border": { - "color": "#e72727", + "color": "#fbbdbd", "width": 1 }, "margin": { diff --git a/styles/figma/core.json b/styles/figma/core.json index 77dabe6b4e4462acc636427c388d161bb3c54a33..b3e13f1c7a9f4e048bf7065278ebc1527c4a11cc 100644 --- a/styles/figma/core.json +++ b/styles/figma/core.json @@ -194,42 +194,42 @@ "type": "color" }, "100": { - "value": "#f13455", + "value": "#fdd5db", "step": 100, "type": "color" }, "200": { - "value": "#eb2245", + "value": "#fbbdc8", "step": 200, "type": "color" }, "300": { - "value": "#e7183b", + "value": "#faa4b3", "step": 300, "type": "color" }, "400": { - "value": "#da193a", + "value": "#f98a9d", "step": 400, "type": "color" }, "500": { - "value": "#d01939", + "value": "#f76e86", "step": 500, "type": "color" }, "600": { - "value": "#c81a37", + "value": "#f54c69", "step": 600, "type": "color" }, "700": { - "value": "#c01a36", + "value": "#ec2548", "step": 700, "type": "color" }, "800": { - "value": "#ba1a36", + "value": "#d21939", "step": 800, "type": "color" }, @@ -246,42 +246,42 @@ "type": "color" }, "100": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" }, "200": { - "value": "#e72727", + "value": "#fbbdbd", "step": 200, "type": "color" }, "300": { - "value": "#e31c1c", + "value": "#f9a5a5", "step": 300, "type": "color" }, "400": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "500": { - "value": "#cd1c1c", + "value": "#f47171", "step": 500, "type": "color" }, "600": { - "value": "#c51c1c", + "value": "#f15252", "step": 600, "type": "color" }, "700": { - "value": "#be1c1c", + "value": "#e82c2c", "step": 700, "type": "color" }, "800": { - "value": "#b81c1c", + "value": "#d11c1c", "step": 800, "type": "color" }, @@ -298,42 +298,42 @@ "type": "color" }, "100": { - "value": "#f66e0f", + "value": "#fde0cd", "step": 100, "type": "color" }, "200": { - "value": "#e5660f", + "value": "#fbccac", "step": 200, "type": "color" }, "300": { - "value": "#d66211", + "value": "#fab78b", "step": 300, "type": "color" }, "400": { - "value": "#cc5f13", + "value": "#faa266", "step": 400, "type": "color" }, "500": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" }, "600": { - "value": "#bc5a15", + "value": "#f77113", "step": 600, "type": "color" }, "700": { - "value": "#b65816", + "value": "#e0650f", "step": 700, "type": "color" }, "800": { - "value": "#b15617", + "value": "#c65d14", "step": 800, "type": "color" }, @@ -350,42 +350,42 @@ "type": "color" }, "100": { - "value": "#eb980d", + "value": "#fce7c4", "step": 100, "type": "color" }, "200": { - "value": "#d88e10", + "value": "#fad69d", "step": 200, "type": "color" }, "300": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" }, "400": { - "value": "#c38214", + "value": "#f7b241", "step": 400, "type": "color" }, "500": { - "value": "#bb7e15", + "value": "#f59f0c", "step": 500, "type": "color" }, "600": { - "value": "#b57a16", + "value": "#e1930e", "step": 600, "type": "color" }, "700": { - "value": "#b07717", + "value": "#cd8812", "step": 700, "type": "color" }, "800": { - "value": "#ab7517", + "value": "#ba7d15", "step": 800, "type": "color" }, @@ -402,42 +402,42 @@ "type": "color" }, "100": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "200": { - "value": "#cfa00f", + "value": "#fadc89", "step": 200, "type": "color" }, "300": { - "value": "#c49811", + "value": "#f8cc4e", "step": 300, "type": "color" }, "400": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "500": { - "value": "#b68e14", + "value": "#e5af09", "step": 500, "type": "color" }, "600": { - "value": "#b08a15", + "value": "#d4a30d", "step": 600, "type": "color" }, "700": { - "value": "#ac8615", + "value": "#c49811", "step": 700, "type": "color" }, "800": { - "value": "#a88316", + "value": "#b48d14", "step": 800, "type": "color" }, @@ -454,42 +454,42 @@ "type": "color" }, "100": { - "value": "#80c517", + "value": "#dbf9ac", "step": 100, "type": "color" }, "200": { - "value": "#7aba18", + "value": "#bdf36b", "step": 200, "type": "color" }, "300": { - "value": "#76b318", + "value": "#9feb2b", "step": 300, "type": "color" }, "400": { - "value": "#72ad19", + "value": "#90df17", "step": 400, "type": "color" }, "500": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "600": { - "value": "#6ea519", + "value": "#7fc417", "step": 600, "type": "color" }, "700": { - "value": "#6ca219", + "value": "#78b618", "step": 700, "type": "color" }, "800": { - "value": "#6a9f1a", + "value": "#70aa19", "step": 800, "type": "color" }, @@ -506,42 +506,42 @@ "type": "color" }, "100": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" }, "200": { - "value": "#20b557", + "value": "#8ff4b2", "step": 200, "type": "color" }, "300": { - "value": "#1faf54", + "value": "#60ec92", "step": 300, "type": "color" }, "400": { - "value": "#1faa52", + "value": "#34e173", "step": 400, "type": "color" }, "500": { - "value": "#1ea650", + "value": "#23d464", "step": 500, "type": "color" }, "600": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "700": { - "value": "#1da04d", + "value": "#20b658", "step": 700, "type": "color" }, "800": { - "value": "#1d9d4c", + "value": "#1ea851", "step": 800, "type": "color" }, @@ -558,42 +558,42 @@ "type": "color" }, "100": { - "value": "#11b47e", + "value": "#b3fbe3", "step": 100, "type": "color" }, "200": { - "value": "#13ac79", + "value": "#72f6ca", "step": 200, "type": "color" }, "300": { - "value": "#14a776", + "value": "#1feda9", "step": 300, "type": "color" }, "400": { - "value": "#15a374", + "value": "#12e09b", "step": 400, "type": "color" }, "500": { - "value": "#16a072", + "value": "#11d091", "step": 500, "type": "color" }, "600": { - "value": "#169d70", + "value": "#11c287", "step": 600, "type": "color" }, "700": { - "value": "#179b6f", + "value": "#11b37e", "step": 700, "type": "color" }, "800": { - "value": "#17996e", + "value": "#15a575", "step": 800, "type": "color" }, @@ -610,42 +610,42 @@ "type": "color" }, "100": { - "value": "#15b3a2", + "value": "#b4faf2", "step": 100, "type": "color" }, "200": { - "value": "#16ab9b", + "value": "#73f4e6", "step": 200, "type": "color" }, "300": { - "value": "#17a696", + "value": "#26ebd5", "step": 300, "type": "color" }, "400": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" }, "500": { - "value": "#189f90", + "value": "#15cfba", "step": 500, "type": "color" }, "600": { - "value": "#189d8e", + "value": "#15c1ae", "step": 600, "type": "color" }, "700": { - "value": "#189a8c", + "value": "#15b2a1", "step": 700, "type": "color" }, "800": { - "value": "#19988a", + "value": "#17a495", "step": 800, "type": "color" }, @@ -662,42 +662,42 @@ "type": "color" }, "100": { - "value": "#09b5cc", + "value": "#bcf5fc", "step": 100, "type": "color" }, "200": { - "value": "#0daabf", + "value": "#86edfa", "step": 200, "type": "color" }, "300": { - "value": "#0fa3b7", + "value": "#41e3f8", "step": 300, "type": "color" }, "400": { - "value": "#119eb1", + "value": "#07d5f1", "step": 400, "type": "color" }, "500": { - "value": "#1299ac", + "value": "#07c7e1", "step": 500, "type": "color" }, "600": { - "value": "#1396a8", + "value": "#07b8d0", "step": 600, "type": "color" }, "700": { - "value": "#1493a4", + "value": "#0daabf", "step": 700, "type": "color" }, "800": { - "value": "#1590a1", + "value": "#119bae", "step": 800, "type": "color" }, @@ -714,42 +714,42 @@ "type": "color" }, "100": { - "value": "#109fdf", + "value": "#caecfc", "step": 100, "type": "color" }, "200": { - "value": "#1394cf", + "value": "#a6defa", "step": 200, "type": "color" }, "300": { - "value": "#148dc4", + "value": "#81d2f8", "step": 300, "type": "color" }, "400": { - "value": "#1588bc", + "value": "#59c3f5", "step": 400, "type": "color" }, "500": { - "value": "#1684b6", + "value": "#2db4f3", "step": 500, "type": "color" }, "600": { - "value": "#1780b0", + "value": "#0ea5e8", "step": 600, "type": "color" }, "700": { - "value": "#177dac", + "value": "#1296d1", "step": 700, "type": "color" }, "800": { - "value": "#187ba8", + "value": "#1686ba", "step": 800, "type": "color" }, @@ -766,42 +766,42 @@ "type": "color" }, "100": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "200": { - "value": "#1f6eed", + "value": "#b4cffb", "step": 200, "type": "color" }, "300": { - "value": "#1666e7", + "value": "#99befa", "step": 300, "type": "color" }, "400": { - "value": "#1762db", + "value": "#7cacf9", "step": 400, "type": "color" }, "500": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "600": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" }, "700": { - "value": "#1959c0", + "value": "#2774f0", "step": 700, "type": "color" }, "800": { - "value": "#1957ba", + "value": "#1762db", "step": 800, "type": "color" }, @@ -818,42 +818,42 @@ "type": "color" }, "100": { - "value": "#5558ee", + "value": "#d4d5fd", "step": 100, "type": "color" }, "200": { - "value": "#3d41e9", + "value": "#bebefb", "step": 200, "type": "color" }, "300": { - "value": "#2e32e5", + "value": "#a7a8f9", "step": 300, "type": "color" }, "400": { - "value": "#2327e2", + "value": "#8f90f6", "step": 400, "type": "color" }, "500": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "600": { - "value": "#1e22d1", + "value": "#5f62f0", "step": 600, "type": "color" }, "700": { - "value": "#1e21c9", + "value": "#464aeb", "step": 700, "type": "color" }, "800": { - "value": "#1e21c1", + "value": "#292de4", "step": 800, "type": "color" }, @@ -870,42 +870,42 @@ "type": "color" }, "100": { - "value": "#804ef3", + "value": "#e0d5fd", "step": 100, "type": "color" }, "200": { - "value": "#6e37ee", + "value": "#cfbcfb", "step": 200, "type": "color" }, "300": { - "value": "#6329e9", + "value": "#bda4fa", "step": 300, "type": "color" }, "400": { - "value": "#5a1ee6", + "value": "#ad8cf9", "step": 400, "type": "color" }, "500": { - "value": "#551bde", + "value": "#9b73f7", "step": 500, "type": "color" }, "600": { - "value": "#531bd4", + "value": "#8959f6", "step": 600, "type": "color" }, "700": { - "value": "#501bcb", + "value": "#7540f0", "step": 700, "type": "color" }, "800": { - "value": "#4e1bc3", + "value": "#5e22e7", "step": 800, "type": "color" }, @@ -922,42 +922,42 @@ "type": "color" }, "100": { - "value": "#a048f4", + "value": "#e9d4fd", "step": 100, "type": "color" }, "200": { - "value": "#9332ee", + "value": "#dcbcfc", "step": 200, "type": "color" }, "300": { - "value": "#8a24ea", + "value": "#d0a4fa", "step": 300, "type": "color" }, "400": { - "value": "#831ae7", + "value": "#c38bf9", "step": 400, "type": "color" }, "500": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" }, "600": { - "value": "#781ad2", + "value": "#a856f7", "step": 600, "type": "color" }, "700": { - "value": "#741ac9", + "value": "#9739f1", "step": 700, "type": "color" }, "800": { - "value": "#701bc2", + "value": "#831ae6", "step": 800, "type": "color" }, @@ -974,42 +974,42 @@ "type": "color" }, "100": { - "value": "#d63be2", + "value": "#fad4fc", "step": 100, "type": "color" }, "200": { - "value": "#d12ade", + "value": "#f6bbfa", "step": 200, "type": "color" }, "300": { - "value": "#ca23d6", + "value": "#f1a2f7", "step": 300, "type": "color" }, "400": { - "value": "#c122cc", + "value": "#ec8af3", "step": 400, "type": "color" }, "500": { - "value": "#b921c4", + "value": "#e56fee", "step": 500, "type": "color" }, "600": { - "value": "#b320bd", + "value": "#dd51e7", "step": 600, "type": "color" }, "700": { - "value": "#ad20b7", + "value": "#d32edf", "step": 700, "type": "color" }, "800": { - "value": "#a81fb2", + "value": "#bc21c8", "step": 800, "type": "color" }, @@ -1026,42 +1026,42 @@ "type": "color" }, "100": { - "value": "#e93d92", + "value": "#fcd4e8", "step": 100, "type": "color" }, "200": { - "value": "#e42a87", + "value": "#fbbcdb", "step": 200, "type": "color" }, "300": { - "value": "#e11e7f", + "value": "#f8a5ce", "step": 300, "type": "color" }, "400": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" }, "500": { - "value": "#cc1e75", + "value": "#f26fb0", "step": 500, "type": "color" }, "600": { - "value": "#c41e71", + "value": "#ee519e", "step": 600, "type": "color" }, "700": { - "value": "#bd1d6d", + "value": "#e52e89", "step": 700, "type": "color" }, "800": { - "value": "#b71d6a", + "value": "#ce1e76", "step": 800, "type": "color" }, diff --git a/styles/figma/dark.json b/styles/figma/dark.json index fadaf7c19e3459fb3b20cd9af5fc930a2231f010..568f53b8154003fb1805de4c2ae420f0f2a94e89 100644 --- a/styles/figma/dark.json +++ b/styles/figma/dark.json @@ -29,27 +29,27 @@ "type": "color" }, "feature": { - "value": "#1684b6", + "value": "#2db4f3", "step": 500, "type": "color" }, "ok": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "error": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "warning": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" }, "info": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } @@ -81,27 +81,27 @@ "type": "color" }, "feature": { - "value": "#1684b6", + "value": "#2db4f3", "step": 500, "type": "color" }, "ok": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "error": { - "value": "#cd1c1c", + "value": "#f47171", "step": 500, "type": "color" }, "warning": { - "value": "#c38214", + "value": "#f7b241", "step": 400, "type": "color" }, "info": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" } @@ -175,88 +175,88 @@ }, "ok": { "base": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "hovered": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "active": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "focused": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" } }, "error": { "base": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "hovered": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "active": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "focused": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" } }, "warning": { "base": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" }, "hovered": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" }, "active": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" }, "focused": { - "value": "#cc8712", + "value": "#f8c570", "step": 300, "type": "color" } }, "info": { "base": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "hovered": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "active": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "focused": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } @@ -289,22 +289,22 @@ "type": "color" }, "ok": { - "value": "#1ea650", + "value": "#23d464", "step": 500, "type": "color" }, "error": { - "value": "#cd1c1c", + "value": "#f47171", "step": 500, "type": "color" }, "warning": { - "value": "#bb7e15", + "value": "#f59f0c", "step": 500, "type": "color" }, "info": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } @@ -337,34 +337,34 @@ "type": "color" }, "inserted": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "deleted": { - "value": "#d71c1c", + "value": "#f78c8c", "step": 400, "type": "color" }, "modified": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } }, "highlight": { "selection": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "occurrence": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "activeOccurrence": { - "value": "#2327e2", + "value": "#8f90f6", "step": 400, "type": "color" }, @@ -374,12 +374,12 @@ "type": "color" }, "match": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "activeMatch": { - "value": "#72ad19", + "value": "#90df17", "step": 400, "type": "color" }, @@ -408,39 +408,39 @@ "type": "color" }, "comment": { - "value": "#7aba18", + "value": "#bdf36b", "type": "color" }, "keyword": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "function": { - "value": "#cfa00f", + "value": "#fadc89", "type": "color" }, "type": { - "value": "#17a696", + "value": "#26ebd5", "type": "color" }, "variant": { - "value": "#17a696", + "value": "#26ebd5", "type": "color" }, "property": { - "value": "#148dc4", + "value": "#81d2f8", "type": "color" }, "enum": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "operator": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "string": { - "value": "#d66211", + "value": "#fab78b", "type": "color" }, "number": { @@ -455,176 +455,176 @@ "player": { "1": { "baseColor": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" }, "cursorColor": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" }, "selectionColor": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" } }, "2": { "baseColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "cursorColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "selectionColor": { - "value": "#80c517", + "value": "#dbf9ac", "step": 100, "type": "color" }, "borderColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" } }, "3": { "baseColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "cursorColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "selectionColor": { - "value": "#5558ee", + "value": "#d4d5fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" } }, "4": { "baseColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" }, "cursorColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" }, "selectionColor": { - "value": "#f66e0f", + "value": "#fde0cd", "step": 100, "type": "color" }, "borderColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" } }, "5": { "baseColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" }, "cursorColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" }, "selectionColor": { - "value": "#a048f4", + "value": "#e9d4fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" } }, "6": { "baseColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" }, "cursorColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" }, "selectionColor": { - "value": "#15b3a2", + "value": "#b4faf2", "step": 100, "type": "color" }, "borderColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" } }, "7": { "baseColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" }, "cursorColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" }, "selectionColor": { - "value": "#e93d92", + "value": "#fcd4e8", "step": 100, "type": "color" }, "borderColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" } }, "8": { "baseColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "cursorColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "selectionColor": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "borderColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" } diff --git a/styles/figma/light.json b/styles/figma/light.json index 415ab40933c5be2c343b8174c95c9e9917e76675..c8ef9e5dcd69332fc33abda730f08b7f7190d574 100644 --- a/styles/figma/light.json +++ b/styles/figma/light.json @@ -29,27 +29,27 @@ "type": "color" }, "feature": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "ok": { - "value": "#1ea650", + "value": "#23d464", "step": 500, "type": "color" }, "error": { - "value": "#cd1c1c", + "value": "#f47171", "step": 500, "type": "color" }, "warning": { - "value": "#b68e14", + "value": "#e5af09", "step": 500, "type": "color" }, "info": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } @@ -81,27 +81,27 @@ "type": "color" }, "feature": { - "value": "#1780b0", + "value": "#0ea5e8", "step": 600, "type": "color" }, "ok": { - "value": "#1ea34f", + "value": "#22c55e", "step": 600, "type": "color" }, "error": { - "value": "#c51c1c", + "value": "#f15252", "step": 600, "type": "color" }, "warning": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "info": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" } @@ -175,88 +175,88 @@ }, "ok": { "base": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" }, "hovered": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" }, "active": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" }, "focused": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" } }, "error": { "base": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" }, "hovered": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" }, "active": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" }, "focused": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" } }, "warning": { "base": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "hovered": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "active": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "focused": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" } }, "info": { "base": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "hovered": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "active": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "focused": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" } @@ -289,22 +289,22 @@ "type": "color" }, "ok": { - "value": "#20b557", + "value": "#8ff4b2", "step": 200, "type": "color" }, "error": { - "value": "#e72727", + "value": "#fbbdbd", "step": 200, "type": "color" }, "warning": { - "value": "#cfa00f", + "value": "#fadc89", "step": 200, "type": "color" }, "info": { - "value": "#1f6eed", + "value": "#b4cffb", "step": 200, "type": "color" } @@ -337,24 +337,24 @@ "type": "color" }, "inserted": { - "value": "#21bf5b", + "value": "#befad2", "step": 100, "type": "color" }, "deleted": { - "value": "#ec3939", + "value": "#fdd4d4", "step": 100, "type": "color" }, "modified": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" } }, "highlight": { "selection": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, @@ -408,39 +408,39 @@ "type": "color" }, "comment": { - "value": "#7aba18", + "value": "#bdf36b", "type": "color" }, "keyword": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "function": { - "value": "#cfa00f", + "value": "#fadc89", "type": "color" }, "type": { - "value": "#17a696", + "value": "#26ebd5", "type": "color" }, "variant": { - "value": "#17a696", + "value": "#26ebd5", "type": "color" }, "property": { - "value": "#148dc4", + "value": "#81d2f8", "type": "color" }, "enum": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "operator": { - "value": "#1588bc", + "value": "#59c3f5", "type": "color" }, "string": { - "value": "#d66211", + "value": "#fab78b", "type": "color" }, "number": { @@ -455,176 +455,176 @@ "player": { "1": { "baseColor": { - "value": "#195cc8", + "value": "#4287f6", "step": 600, "type": "color" }, "cursorColor": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" }, "selectionColor": { - "value": "#307af3", + "value": "#d0e2fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#185fd0", + "value": "#6099f7", "step": 500, "type": "color" } }, "2": { "baseColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "cursorColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" }, "selectionColor": { - "value": "#80c517", + "value": "#dbf9ac", "step": 100, "type": "color" }, "borderColor": { - "value": "#70a919", + "value": "#87d116", "step": 500, "type": "color" } }, "3": { "baseColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "cursorColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" }, "selectionColor": { - "value": "#5558ee", + "value": "#d4d5fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#1e22db", + "value": "#777af4", "step": 500, "type": "color" } }, "4": { "baseColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" }, "cursorColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" }, "selectionColor": { - "value": "#f66e0f", + "value": "#fde0cd", "step": 100, "type": "color" }, "borderColor": { - "value": "#c45c14", + "value": "#f98a3d", "step": 500, "type": "color" } }, "5": { "baseColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" }, "cursorColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" }, "selectionColor": { - "value": "#a048f4", + "value": "#e9d4fd", "step": 100, "type": "color" }, "borderColor": { - "value": "#7d19dc", + "value": "#b671f8", "step": 500, "type": "color" } }, "6": { "baseColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" }, "cursorColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" }, "selectionColor": { - "value": "#15b3a2", + "value": "#b4faf2", "step": 100, "type": "color" }, "borderColor": { - "value": "#17a293", + "value": "#16ddc7", "step": 400, "type": "color" } }, "7": { "baseColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" }, "cursorColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" }, "selectionColor": { - "value": "#e93d92", + "value": "#fcd4e8", "step": 100, "type": "color" }, "borderColor": { - "value": "#d51e79", + "value": "#f58ac0", "step": 400, "type": "color" } }, "8": { "baseColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "cursorColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" }, "selectionColor": { - "value": "#e0ac0b", + "value": "#fceabc", "step": 100, "type": "color" }, "borderColor": { - "value": "#bc9212", + "value": "#f6bc09", "step": 400, "type": "color" } diff --git a/styles/utils/color.ts b/styles/utils/color.ts index c7506f696d4cebd54ebc2045be2b7dc9d14f2c7b..156fc5ba41b2bbf0cfc9dd8080db9bf6cd6c320d 100644 --- a/styles/utils/color.ts +++ b/styles/utils/color.ts @@ -22,8 +22,8 @@ export function colorRamp( .scale([startColor, color, endColor]) .domain([0, 0.5, 1]) .mode("hsl") - .gamma(0.2) - // .correctLightness(true) + .gamma(1) + .correctLightness(true) .padding([0, 0.15]); } From a3fc719a526e985d5f5296471751ac94b020f55e Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 15:03:38 -0400 Subject: [PATCH 67/68] Add a combined `tokens.json` for Figma Tokens - Having individual json files for themes and core is useful for copy+pasting while exploring changes - Figma github sync requires a single json file to pull down --- styles/buildFigmaTokens.ts | 42 +- styles/figma/tokens.json | 2431 ++++++++++++++++++++++++++++++++++++ 2 files changed, 2460 insertions(+), 13 deletions(-) create mode 100644 styles/figma/tokens.json diff --git a/styles/buildFigmaTokens.ts b/styles/buildFigmaTokens.ts index 6b3285e58e24c7f0fefa67a40c512202fdbe4c5b..bb77046e85c53007c272ac791e104b9a908fd80d 100644 --- a/styles/buildFigmaTokens.ts +++ b/styles/buildFigmaTokens.ts @@ -5,8 +5,13 @@ import light from "./themes/light"; import Theme from "./themes/theme"; import { colors, fontFamilies, fontSizes, fontWeights } from "./tokens"; +let themes = [ + dark, + light +]; + // Organize theme tokens -function themeTokens(theme: Theme): Object { +function themeTokens(theme: Theme) { return { meta: { themeName: theme.name, @@ -71,16 +76,6 @@ function themeTokens(theme: Theme): Object { }; } -let themes = [themeTokens(dark), themeTokens(light)]; - -// Create {theme}.json -const themePath = path.resolve(`${__dirname}/figma`); -themes.forEach((theme) => { - const tokenJSON = JSON.stringify(theme, null, 2); - //@ts-ignore //TODO: IDK what the hell TS wants me to do here - fs.writeFileSync(`${themePath}/${theme.meta.themeName}.json`, tokenJSON); -}); - // Organize core tokens const coreTokens = { color: { @@ -93,7 +88,28 @@ const coreTokens = { size: fontSizes, }; +const combinedTokens = { + core: coreTokens, + dark: themeTokens(dark), + light: themeTokens(light) +} + // Create core.json const corePath = path.resolve(`${__dirname}/figma/core.json`); -const coreTokenJSON = JSON.stringify(coreTokens, null, 2); -fs.writeFileSync(corePath, coreTokenJSON); +const coreJSON = JSON.stringify(coreTokens, null, 2); +fs.writeFileSync(corePath, coreJSON); +console.log(`- Core: core.json created`); + +// Create {theme}.json +const themePath = path.resolve(`${__dirname}/figma`); +themes.forEach((theme) => { + const tokenJSON = JSON.stringify(themeTokens(theme), null, 2); + fs.writeFileSync(`${themePath}/${theme.name}.json`, tokenJSON); + console.log(`- Theme: ${theme.name}.json created`); +}); + +// Create combined tokens.json +const combinedPath = path.resolve(`${__dirname}/figma/tokens.json`); +const combinedJSON = JSON.stringify(combinedTokens, null, 2); +fs.writeFileSync(combinedPath, combinedJSON); +console.log(`- Combined: tokens.json created`); \ No newline at end of file diff --git a/styles/figma/tokens.json b/styles/figma/tokens.json new file mode 100644 index 0000000000000000000000000000000000000000..cffc3ed16de7a4dec1fa38fa2026243c81629055 --- /dev/null +++ b/styles/figma/tokens.json @@ -0,0 +1,2431 @@ +{ + "core": { + "color": { + "neutral": { + "0": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "25": { + "value": "#f8f8f8", + "step": 25, + "type": "color" + }, + "50": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "75": { + "value": "#eaeaea", + "step": 75, + "type": "color" + }, + "100": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "125": { + "value": "#dcdcdc", + "step": 125, + "type": "color" + }, + "150": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "175": { + "value": "#cdcdcd", + "step": 175, + "type": "color" + }, + "200": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "225": { + "value": "#bfbfbf", + "step": 225, + "type": "color" + }, + "250": { + "value": "#b8b8b8", + "step": 250, + "type": "color" + }, + "275": { + "value": "#b1b1b1", + "step": 275, + "type": "color" + }, + "300": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "325": { + "value": "#a3a3a3", + "step": 325, + "type": "color" + }, + "350": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "375": { + "value": "#959595", + "step": 375, + "type": "color" + }, + "400": { + "value": "#8e8e8e", + "step": 400, + "type": "color" + }, + "425": { + "value": "#878787", + "step": 425, + "type": "color" + }, + "450": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "475": { + "value": "#787878", + "step": 475, + "type": "color" + }, + "500": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "525": { + "value": "#6a6a6a", + "step": 525, + "type": "color" + }, + "550": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "575": { + "value": "#5c5c5c", + "step": 575, + "type": "color" + }, + "600": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "625": { + "value": "#4e4e4e", + "step": 625, + "type": "color" + }, + "650": { + "value": "#474747", + "step": 650, + "type": "color" + }, + "675": { + "value": "#404040", + "step": 675, + "type": "color" + }, + "700": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "725": { + "value": "#323232", + "step": 725, + "type": "color" + }, + "750": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "775": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "800": { + "value": "#1c1c1c", + "step": 800, + "type": "color" + }, + "825": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "850": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "875": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "900": { + "value": "#000000", + "step": 900, + "type": "color" + } + }, + "rose": { + "0": { + "value": "#feecef", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fdd5db", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fbbdc8", + "step": 200, + "type": "color" + }, + "300": { + "value": "#faa4b3", + "step": 300, + "type": "color" + }, + "400": { + "value": "#f98a9d", + "step": 400, + "type": "color" + }, + "500": { + "value": "#f76e86", + "step": 500, + "type": "color" + }, + "600": { + "value": "#f54c69", + "step": 600, + "type": "color" + }, + "700": { + "value": "#ec2548", + "step": 700, + "type": "color" + }, + "800": { + "value": "#d21939", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b41a35", + "step": 900, + "type": "color" + } + }, + "red": { + "0": { + "value": "#feecec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fbbdbd", + "step": 200, + "type": "color" + }, + "300": { + "value": "#f9a5a5", + "step": 300, + "type": "color" + }, + "400": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "500": { + "value": "#f47171", + "step": 500, + "type": "color" + }, + "600": { + "value": "#f15252", + "step": 600, + "type": "color" + }, + "700": { + "value": "#e82c2c", + "step": 700, + "type": "color" + }, + "800": { + "value": "#d11c1c", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b21c1c", + "step": 900, + "type": "color" + } + }, + "orange": { + "0": { + "value": "#fef3ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fde0cd", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fbccac", + "step": 200, + "type": "color" + }, + "300": { + "value": "#fab78b", + "step": 300, + "type": "color" + }, + "400": { + "value": "#faa266", + "step": 400, + "type": "color" + }, + "500": { + "value": "#f98a3d", + "step": 500, + "type": "color" + }, + "600": { + "value": "#f77113", + "step": 600, + "type": "color" + }, + "700": { + "value": "#e0650f", + "step": 700, + "type": "color" + }, + "800": { + "value": "#c65d14", + "step": 800, + "type": "color" + }, + "900": { + "value": "#ac5517", + "step": 900, + "type": "color" + } + }, + "amber": { + "0": { + "value": "#fef7ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fce7c4", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fad69d", + "step": 200, + "type": "color" + }, + "300": { + "value": "#f8c570", + "step": 300, + "type": "color" + }, + "400": { + "value": "#f7b241", + "step": 400, + "type": "color" + }, + "500": { + "value": "#f59f0c", + "step": 500, + "type": "color" + }, + "600": { + "value": "#e1930e", + "step": 600, + "type": "color" + }, + "700": { + "value": "#cd8812", + "step": 700, + "type": "color" + }, + "800": { + "value": "#ba7d15", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a77218", + "step": 900, + "type": "color" + } + }, + "yellow": { + "0": { + "value": "#fef9ec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fadc89", + "step": 200, + "type": "color" + }, + "300": { + "value": "#f8cc4e", + "step": 300, + "type": "color" + }, + "400": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "500": { + "value": "#e5af09", + "step": 500, + "type": "color" + }, + "600": { + "value": "#d4a30d", + "step": 600, + "type": "color" + }, + "700": { + "value": "#c49811", + "step": 700, + "type": "color" + }, + "800": { + "value": "#b48d14", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a48117", + "step": 900, + "type": "color" + } + }, + "lime": { + "0": { + "value": "#f7feec", + "step": 0, + "type": "color" + }, + "100": { + "value": "#dbf9ac", + "step": 100, + "type": "color" + }, + "200": { + "value": "#bdf36b", + "step": 200, + "type": "color" + }, + "300": { + "value": "#9feb2b", + "step": 300, + "type": "color" + }, + "400": { + "value": "#90df17", + "step": 400, + "type": "color" + }, + "500": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "600": { + "value": "#7fc417", + "step": 600, + "type": "color" + }, + "700": { + "value": "#78b618", + "step": 700, + "type": "color" + }, + "800": { + "value": "#70aa19", + "step": 800, + "type": "color" + }, + "900": { + "value": "#699c1a", + "step": 900, + "type": "color" + } + }, + "green": { + "0": { + "value": "#ecfef2", + "step": 0, + "type": "color" + }, + "100": { + "value": "#befad2", + "step": 100, + "type": "color" + }, + "200": { + "value": "#8ff4b2", + "step": 200, + "type": "color" + }, + "300": { + "value": "#60ec92", + "step": 300, + "type": "color" + }, + "400": { + "value": "#34e173", + "step": 400, + "type": "color" + }, + "500": { + "value": "#23d464", + "step": 500, + "type": "color" + }, + "600": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "700": { + "value": "#20b658", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1ea851", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1d9b4b", + "step": 900, + "type": "color" + } + }, + "emerald": { + "0": { + "value": "#ecfef8", + "step": 0, + "type": "color" + }, + "100": { + "value": "#b3fbe3", + "step": 100, + "type": "color" + }, + "200": { + "value": "#72f6ca", + "step": 200, + "type": "color" + }, + "300": { + "value": "#1feda9", + "step": 300, + "type": "color" + }, + "400": { + "value": "#12e09b", + "step": 400, + "type": "color" + }, + "500": { + "value": "#11d091", + "step": 500, + "type": "color" + }, + "600": { + "value": "#11c287", + "step": 600, + "type": "color" + }, + "700": { + "value": "#11b37e", + "step": 700, + "type": "color" + }, + "800": { + "value": "#15a575", + "step": 800, + "type": "color" + }, + "900": { + "value": "#18976c", + "step": 900, + "type": "color" + } + }, + "teal": { + "0": { + "value": "#ecfefc", + "step": 0, + "type": "color" + }, + "100": { + "value": "#b4faf2", + "step": 100, + "type": "color" + }, + "200": { + "value": "#73f4e6", + "step": 200, + "type": "color" + }, + "300": { + "value": "#26ebd5", + "step": 300, + "type": "color" + }, + "400": { + "value": "#16ddc7", + "step": 400, + "type": "color" + }, + "500": { + "value": "#15cfba", + "step": 500, + "type": "color" + }, + "600": { + "value": "#15c1ae", + "step": 600, + "type": "color" + }, + "700": { + "value": "#15b2a1", + "step": 700, + "type": "color" + }, + "800": { + "value": "#17a495", + "step": 800, + "type": "color" + }, + "900": { + "value": "#199788", + "step": 900, + "type": "color" + } + }, + "cyan": { + "0": { + "value": "#ecfcfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#bcf5fc", + "step": 100, + "type": "color" + }, + "200": { + "value": "#86edfa", + "step": 200, + "type": "color" + }, + "300": { + "value": "#41e3f8", + "step": 300, + "type": "color" + }, + "400": { + "value": "#07d5f1", + "step": 400, + "type": "color" + }, + "500": { + "value": "#07c7e1", + "step": 500, + "type": "color" + }, + "600": { + "value": "#07b8d0", + "step": 600, + "type": "color" + }, + "700": { + "value": "#0daabf", + "step": 700, + "type": "color" + }, + "800": { + "value": "#119bae", + "step": 800, + "type": "color" + }, + "900": { + "value": "#168e9e", + "step": 900, + "type": "color" + } + }, + "sky": { + "0": { + "value": "#ecf8fe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#caecfc", + "step": 100, + "type": "color" + }, + "200": { + "value": "#a6defa", + "step": 200, + "type": "color" + }, + "300": { + "value": "#81d2f8", + "step": 300, + "type": "color" + }, + "400": { + "value": "#59c3f5", + "step": 400, + "type": "color" + }, + "500": { + "value": "#2db4f3", + "step": 500, + "type": "color" + }, + "600": { + "value": "#0ea5e8", + "step": 600, + "type": "color" + }, + "700": { + "value": "#1296d1", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1686ba", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1878a4", + "step": 900, + "type": "color" + } + }, + "blue": { + "0": { + "value": "#ecf3fe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "200": { + "value": "#b4cffb", + "step": 200, + "type": "color" + }, + "300": { + "value": "#99befa", + "step": 300, + "type": "color" + }, + "400": { + "value": "#7cacf9", + "step": 400, + "type": "color" + }, + "500": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "600": { + "value": "#4287f6", + "step": 600, + "type": "color" + }, + "700": { + "value": "#2774f0", + "step": 700, + "type": "color" + }, + "800": { + "value": "#1762db", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1a55b4", + "step": 900, + "type": "color" + } + }, + "indigo": { + "0": { + "value": "#ececfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#d4d5fd", + "step": 100, + "type": "color" + }, + "200": { + "value": "#bebefb", + "step": 200, + "type": "color" + }, + "300": { + "value": "#a7a8f9", + "step": 300, + "type": "color" + }, + "400": { + "value": "#8f90f6", + "step": 400, + "type": "color" + }, + "500": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "600": { + "value": "#5f62f0", + "step": 600, + "type": "color" + }, + "700": { + "value": "#464aeb", + "step": 700, + "type": "color" + }, + "800": { + "value": "#292de4", + "step": 800, + "type": "color" + }, + "900": { + "value": "#1d20bb", + "step": 900, + "type": "color" + } + }, + "violet": { + "0": { + "value": "#f1ecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#e0d5fd", + "step": 100, + "type": "color" + }, + "200": { + "value": "#cfbcfb", + "step": 200, + "type": "color" + }, + "300": { + "value": "#bda4fa", + "step": 300, + "type": "color" + }, + "400": { + "value": "#ad8cf9", + "step": 400, + "type": "color" + }, + "500": { + "value": "#9b73f7", + "step": 500, + "type": "color" + }, + "600": { + "value": "#8959f6", + "step": 600, + "type": "color" + }, + "700": { + "value": "#7540f0", + "step": 700, + "type": "color" + }, + "800": { + "value": "#5e22e7", + "step": 800, + "type": "color" + }, + "900": { + "value": "#4c1bbc", + "step": 900, + "type": "color" + } + }, + "purple": { + "0": { + "value": "#f5ecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#e9d4fd", + "step": 100, + "type": "color" + }, + "200": { + "value": "#dcbcfc", + "step": 200, + "type": "color" + }, + "300": { + "value": "#d0a4fa", + "step": 300, + "type": "color" + }, + "400": { + "value": "#c38bf9", + "step": 400, + "type": "color" + }, + "500": { + "value": "#b671f8", + "step": 500, + "type": "color" + }, + "600": { + "value": "#a856f7", + "step": 600, + "type": "color" + }, + "700": { + "value": "#9739f1", + "step": 700, + "type": "color" + }, + "800": { + "value": "#831ae6", + "step": 800, + "type": "color" + }, + "900": { + "value": "#6d1bbb", + "step": 900, + "type": "color" + } + }, + "fuschia": { + "0": { + "value": "#fdecfe", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fad4fc", + "step": 100, + "type": "color" + }, + "200": { + "value": "#f6bbfa", + "step": 200, + "type": "color" + }, + "300": { + "value": "#f1a2f7", + "step": 300, + "type": "color" + }, + "400": { + "value": "#ec8af3", + "step": 400, + "type": "color" + }, + "500": { + "value": "#e56fee", + "step": 500, + "type": "color" + }, + "600": { + "value": "#dd51e7", + "step": 600, + "type": "color" + }, + "700": { + "value": "#d32edf", + "step": 700, + "type": "color" + }, + "800": { + "value": "#bc21c8", + "step": 800, + "type": "color" + }, + "900": { + "value": "#a41ead", + "step": 900, + "type": "color" + } + }, + "pink": { + "0": { + "value": "#feecf5", + "step": 0, + "type": "color" + }, + "100": { + "value": "#fcd4e8", + "step": 100, + "type": "color" + }, + "200": { + "value": "#fbbcdb", + "step": 200, + "type": "color" + }, + "300": { + "value": "#f8a5ce", + "step": 300, + "type": "color" + }, + "400": { + "value": "#f58ac0", + "step": 400, + "type": "color" + }, + "500": { + "value": "#f26fb0", + "step": 500, + "type": "color" + }, + "600": { + "value": "#ee519e", + "step": 600, + "type": "color" + }, + "700": { + "value": "#e52e89", + "step": 700, + "type": "color" + }, + "800": { + "value": "#ce1e76", + "step": 800, + "type": "color" + }, + "900": { + "value": "#b21d67", + "step": 900, + "type": "color" + } + } + }, + "text": { + "family": { + "sans": { + "value": "Zed Sans", + "type": "fontFamily" + }, + "mono": { + "value": "Zed Mono", + "type": "fontFamily" + } + }, + "weight": { + "thin": { + "value": "thin", + "type": "fontWeight" + }, + "extra_light": { + "value": "extra_light", + "type": "fontWeight" + }, + "light": { + "value": "light", + "type": "fontWeight" + }, + "normal": { + "value": "normal", + "type": "fontWeight" + }, + "medium": { + "value": "medium", + "type": "fontWeight" + }, + "semibold": { + "value": "semibold", + "type": "fontWeight" + }, + "bold": { + "value": "bold", + "type": "fontWeight" + }, + "extra_bold": { + "value": "extra_bold", + "type": "fontWeight" + }, + "black": { + "value": "black", + "type": "fontWeight" + } + } + }, + "size": { + "3xs": { + "value": 8, + "type": "fontSize" + }, + "2xs": { + "value": 10, + "type": "fontSize" + }, + "xs": { + "value": 12, + "type": "fontSize" + }, + "sm": { + "value": 14, + "type": "fontSize" + }, + "md": { + "value": 16, + "type": "fontSize" + }, + "lg": { + "value": 18, + "type": "fontSize" + }, + "xl": { + "value": 20, + "type": "fontSize" + } + } + }, + "dark": { + "meta": { + "themeName": "dark" + }, + "text": { + "primary": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "secondary": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "muted": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "placeholder": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "feature": { + "value": "#2db4f3", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "error": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "warning": { + "value": "#f8c570", + "step": 300, + "type": "color" + }, + "info": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "secondary": { + "value": "#9c9c9c", + "step": 350, + "type": "color" + }, + "muted": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "placeholder": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "feature": { + "value": "#2db4f3", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "error": { + "value": "#f47171", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#f7b241", + "step": 400, + "type": "color" + }, + "info": { + "value": "#4287f6", + "step": 600, + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "hovered": { + "value": "#323232", + "step": 725, + "type": "color" + }, + "active": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "focused": { + "value": "#404040", + "step": 675, + "type": "color" + } + }, + "300": { + "base": { + "value": "#1c1c1c", + "step": 800, + "type": "color" + }, + "hovered": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "active": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "focused": { + "value": "#323232", + "step": 725, + "type": "color" + } + }, + "500": { + "base": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "hovered": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "active": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "focused": { + "value": "#151515", + "step": 825, + "type": "color" + } + }, + "ok": { + "base": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "hovered": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "active": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "focused": { + "value": "#22c55e", + "step": 600, + "type": "color" + } + }, + "error": { + "base": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "hovered": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "active": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "focused": { + "value": "#f78c8c", + "step": 400, + "type": "color" + } + }, + "warning": { + "base": { + "value": "#f8c570", + "step": 300, + "type": "color" + }, + "hovered": { + "value": "#f8c570", + "step": 300, + "type": "color" + }, + "active": { + "value": "#f8c570", + "step": 300, + "type": "color" + }, + "focused": { + "value": "#f8c570", + "step": 300, + "type": "color" + } + }, + "info": { + "base": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "hovered": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "active": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "focused": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "secondary": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "muted": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "focused": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "ok": { + "value": "#23d464", + "step": 500, + "type": "color" + }, + "error": { + "value": "#f47171", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#f59f0c", + "step": 500, + "type": "color" + }, + "info": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + }, + "editor": { + "background": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "indent_guide": { + "value": "#232323", + "step": 775, + "type": "color" + }, + "indent_guide_active": { + "value": "#151515", + "step": 825, + "type": "color" + }, + "line": { + "active": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "highlighted": { + "value": "#070707", + "step": 875, + "type": "color" + }, + "inserted": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "deleted": { + "value": "#f78c8c", + "step": 400, + "type": "color" + }, + "modified": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "occurrence": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "activeOccurrence": { + "value": "#8f90f6", + "step": 400, + "type": "color" + }, + "matchingBracket": { + "value": "#0e0e0e", + "step": 850, + "type": "color" + }, + "match": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "activeMatch": { + "value": "#90df17", + "step": 400, + "type": "color" + }, + "related": { + "value": "#151515", + "step": 825, + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#636363", + "step": 550, + "type": "color" + }, + "active": { + "value": "#ffffff", + "step": 0, + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#f1f1f1", + "type": "color" + }, + "comment": { + "value": "#bdf36b", + "type": "color" + }, + "keyword": { + "value": "#59c3f5", + "type": "color" + }, + "function": { + "value": "#fadc89", + "type": "color" + }, + "type": { + "value": "#26ebd5", + "type": "color" + }, + "variant": { + "value": "#26ebd5", + "type": "color" + }, + "property": { + "value": "#81d2f8", + "type": "color" + }, + "enum": { + "value": "#59c3f5", + "type": "color" + }, + "operator": { + "value": "#59c3f5", + "type": "color" + }, + "string": { + "value": "#fab78b", + "type": "color" + }, + "number": { + "value": "#d5d5d5", + "type": "color" + }, + "boolean": { + "value": "#d5d5d5", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#4287f6", + "step": 600, + "type": "color" + }, + "cursorColor": { + "value": "#4287f6", + "step": 600, + "type": "color" + }, + "selectionColor": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#4287f6", + "step": 600, + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#dbf9ac", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#87d116", + "step": 500, + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#d4d5fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#777af4", + "step": 500, + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#fde0cd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#e9d4fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#b4faf2", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#fcd4e8", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.32, + "type": "number" + } + }, + "light": { + "meta": { + "themeName": "light" + }, + "text": { + "primary": { + "value": "#2b2b2b", + "step": 750, + "type": "color" + }, + "secondary": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "muted": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "placeholder": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "feature": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "ok": { + "value": "#23d464", + "step": 500, + "type": "color" + }, + "error": { + "value": "#f47171", + "step": 500, + "type": "color" + }, + "warning": { + "value": "#e5af09", + "step": 500, + "type": "color" + }, + "info": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#aaaaaa", + "step": 300, + "type": "color" + }, + "secondary": { + "value": "#717171", + "step": 500, + "type": "color" + }, + "muted": { + "value": "#555555", + "step": 600, + "type": "color" + }, + "placeholder": { + "value": "#393939", + "step": 700, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + }, + "feature": { + "value": "#0ea5e8", + "step": 600, + "type": "color" + }, + "ok": { + "value": "#22c55e", + "step": 600, + "type": "color" + }, + "error": { + "value": "#f15252", + "step": 600, + "type": "color" + }, + "warning": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "info": { + "value": "#4287f6", + "step": 600, + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "active": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "focused": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + } + }, + "300": { + "base": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "hovered": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "active": { + "value": "#d5d5d5", + "step": 150, + "type": "color" + }, + "focused": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + } + }, + "500": { + "base": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "hovered": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + } + }, + "ok": { + "base": { + "value": "#befad2", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#befad2", + "step": 100, + "type": "color" + }, + "active": { + "value": "#befad2", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#befad2", + "step": 100, + "type": "color" + } + }, + "error": { + "base": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + }, + "active": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + } + }, + "warning": { + "base": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "active": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#fceabc", + "step": 100, + "type": "color" + } + }, + "info": { + "base": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "hovered": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "active": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "focused": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#c6c6c6", + "step": 200, + "type": "color" + }, + "secondary": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "muted": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "focused": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "active": { + "value": "#b8b8b8", + "step": 250, + "type": "color" + }, + "ok": { + "value": "#8ff4b2", + "step": 200, + "type": "color" + }, + "error": { + "value": "#fbbdbd", + "step": 200, + "type": "color" + }, + "warning": { + "value": "#fadc89", + "step": 200, + "type": "color" + }, + "info": { + "value": "#b4cffb", + "step": 200, + "type": "color" + } + }, + "editor": { + "background": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "indent_guide": { + "value": "#f1f1f1", + "step": 50, + "type": "color" + }, + "indent_guide_active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "line": { + "active": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "highlighted": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "inserted": { + "value": "#befad2", + "step": 100, + "type": "color" + }, + "deleted": { + "value": "#fdd4d4", + "step": 100, + "type": "color" + }, + "modified": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "occurrence": { + "value": "#e3e3e3", + "step": 100, + "type": "color" + }, + "activeOccurrence": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "matchingBracket": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "match": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "activeMatch": { + "value": "#ffffff", + "step": 0, + "type": "color" + }, + "related": { + "value": "#ffffff", + "step": 0, + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#808080", + "step": 450, + "type": "color" + }, + "active": { + "value": "#000000", + "step": 900, + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#2b2b2b", + "type": "color" + }, + "comment": { + "value": "#bdf36b", + "type": "color" + }, + "keyword": { + "value": "#59c3f5", + "type": "color" + }, + "function": { + "value": "#fadc89", + "type": "color" + }, + "type": { + "value": "#26ebd5", + "type": "color" + }, + "variant": { + "value": "#26ebd5", + "type": "color" + }, + "property": { + "value": "#81d2f8", + "type": "color" + }, + "enum": { + "value": "#59c3f5", + "type": "color" + }, + "operator": { + "value": "#59c3f5", + "type": "color" + }, + "string": { + "value": "#fab78b", + "type": "color" + }, + "number": { + "value": "#d5d5d5", + "type": "color" + }, + "boolean": { + "value": "#d5d5d5", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#4287f6", + "step": 600, + "type": "color" + }, + "cursorColor": { + "value": "#6099f7", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#d0e2fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#6099f7", + "step": 500, + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#87d116", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#dbf9ac", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#87d116", + "step": 500, + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#777af4", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#d4d5fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#777af4", + "step": 500, + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#fde0cd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f98a3d", + "step": 500, + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + }, + "cursorColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + }, + "selectionColor": { + "value": "#e9d4fd", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#b671f8", + "step": 500, + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#b4faf2", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#16ddc7", + "step": 400, + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#fcd4e8", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f58ac0", + "step": 400, + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "cursorColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + }, + "selectionColor": { + "value": "#fceabc", + "step": 100, + "type": "color" + }, + "borderColor": { + "value": "#f6bc09", + "step": 400, + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.12, + "type": "number" + } + } +} \ No newline at end of file From 3dc99a874330b0a93afa5f41956b9e687e8a967d Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sun, 3 Apr 2022 21:15:14 -0400 Subject: [PATCH 68/68] Update dark, light themes. --- crates/zed/assets/themes/dark.json | 130 +++++++++++++++---------- crates/zed/assets/themes/light.json | 142 +++++++++++++++++----------- styles/styleTree/editor.ts | 20 +++- styles/styleTree/workspace.ts | 2 +- styles/themes/dark.ts | 48 +++++----- styles/themes/light.ts | 38 ++++---- styles/utils/color.ts | 6 +- 7 files changed, 228 insertions(+), 158 deletions(-) diff --git a/crates/zed/assets/themes/dark.json b/crates/zed/assets/themes/dark.json index da7fa4650ee609d46ce2eacf5dcf8eb4a3f8088c..1334a65727f8d099b5bc363fd0e432ef828808ba 100644 --- a/crates/zed/assets/themes/dark.json +++ b/crates/zed/assets/themes/dark.json @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#1096d3", "weight": "bold", "size": 14 } @@ -38,7 +38,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#2db4f3", + "color": "#1096d3", "weight": "bold", "size": 14 }, @@ -70,8 +70,8 @@ "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#103063" }, "text": { "family": "Zed Mono", @@ -111,8 +111,8 @@ "background": "#1c1c1c", "icon_close": "#555555", "icon_close_active": "#ffffff", - "icon_conflict": "#f7b241", - "icon_dirty": "#4287f6", + "icon_conflict": "#f6a724", + "icon_dirty": "#135acd", "icon_width": 8, "spacing": 10, "text": { @@ -137,8 +137,8 @@ "background": "#000000", "icon_close": "#555555", "icon_close_active": "#ffffff", - "icon_conflict": "#f7b241", - "icon_dirty": "#4287f6", + "icon_conflict": "#f6a724", + "icon_dirty": "#135acd", "icon_width": 8, "spacing": 10, "text": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#f7bb57", "size": 13 } }, @@ -297,7 +297,7 @@ "height": 34, "background": "#000000", "border": { - "color": "#070707", + "color": "#151515", "width": 1, "bottom": true }, @@ -325,54 +325,54 @@ } }, "editor": { - "text_color": "#f1f1f1", + "text_color": "#d5d5d5", "background": "#000000", "active_line_background": "#0e0e0e", "code_actions_indicator": "#9c9c9c", - "diff_background_deleted": "#f78c8c", - "diff_background_inserted": "#22c55e", - "document_highlight_read_background": "#777af4", - "document_highlight_write_background": "#777af4", - "error_color": "#f78c8c", + "diff_background_deleted": "#f15656", + "diff_background_inserted": "#1b9447", + "document_highlight_read_background": "#2b2b2b", + "document_highlight_write_background": "#2b2b2b", + "error_color": "#f15656", "gutter_background": "#000000", - "gutter_padding_factor": 2.5, + "gutter_padding_factor": 3.5, "highlighted_line_background": "#070707", "line_number": "#636363", "line_number_active": "#ffffff", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#4287f6", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#103063" }, "guest_selections": [ { - "cursor": "#87d116", - "selection": "#dbf9ac" + "cursor": "#79ba16", + "selection": "#38530f" }, { - "cursor": "#777af4", - "selection": "#d4d5fd" + "cursor": "#484bed", + "selection": "#121269" }, { - "cursor": "#f98a3d", - "selection": "#fde0cd" + "cursor": "#ee670a", + "selection": "#5d2f0e" }, { - "cursor": "#b671f8", - "selection": "#e9d4fd" + "cursor": "#993bf3", + "selection": "#3e1169" }, { - "cursor": "#16ddc7", - "selection": "#b4faf2" + "cursor": "#16d6c1", + "selection": "#0e4f48" }, { - "cursor": "#f58ac0", - "selection": "#fcd4e8" + "cursor": "#ef59a3", + "selection": "#fbc6e1" }, { - "cursor": "#f6bc09", - "selection": "#fceabc" + "cursor": "#f7bf17", + "selection": "#fce9b7" } ], "autocomplete": { @@ -406,7 +406,7 @@ "left": -14 }, "match_highlight": { - "color": "#59c3f5", + "color": "#4f8ff7", "weight": "normal" }, "selected_item": { @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#f15656", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f78c8c", + "color": "#f15656", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#f7bb57", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f8c570", + "color": "#f7bb57", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14, "weight": "bold" } @@ -653,7 +653,35 @@ } } }, - "syntax": {} + "syntax": { + "keyword": "#4f8ff7", + "function": "#f9da82", + "string": "#f99d5f", + "type": "#3eeeda", + "number": "#aeef4b", + "comment": "#aaaaaa", + "property": "#4f8ff7", + "variant": "#53c1f5", + "constant": "#d5d5d5", + "title": { + "color": "#de900c", + "weight": "bold" + }, + "emphasis": "#1096d3", + "emphasis_strong": { + "color": "#1096d3", + "weight": "bold" + }, + "link_uri": { + "color": "#79ba16", + "underline": true + }, + "link_text": { + "color": "#ee670a", + "italic": true + }, + "list_marker": "#20b0f2" + } }, "project_diagnostics": { "tab_icon_spacing": 4, @@ -929,8 +957,8 @@ "size": 14 }, "selection": { - "cursor": "#4287f6", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#103063" }, "border": { "color": "#151515", @@ -1067,7 +1095,7 @@ } }, "search": { - "match_background": "#87d116", + "match_background": "#0a2633", "tab_icon_spacing": 4, "tab_icon_width": 14, "active_hovered_option_button": { @@ -1123,8 +1151,8 @@ "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#103063" }, "text": { "family": "Zed Mono", @@ -1177,8 +1205,8 @@ "size": 16 }, "selection": { - "cursor": "#4287f6", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#103063" }, "text": { "family": "Zed Mono", @@ -1186,7 +1214,7 @@ "size": 16 }, "border": { - "color": "#f47171", + "color": "#eb2d2d", "width": 1 }, "margin": { diff --git a/crates/zed/assets/themes/light.json b/crates/zed/assets/themes/light.json index dcff3352f75703a64030db29cde7797dd038c432..283b3b10b32e3886fe15736e8e6d9cbb7091e3a5 100644 --- a/crates/zed/assets/themes/light.json +++ b/crates/zed/assets/themes/light.json @@ -18,7 +18,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "weight": "bold", "size": 14 } @@ -38,7 +38,7 @@ }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "weight": "bold", "size": 14 }, @@ -70,8 +70,8 @@ "size": 14 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#c5dafc" }, "text": { "family": "Zed Mono", @@ -111,8 +111,8 @@ "background": "#f1f1f1", "icon_close": "#555555", "icon_close_active": "#000000", - "icon_conflict": "#f6bc09", - "icon_dirty": "#4287f6", + "icon_conflict": "#f7bf17", + "icon_dirty": "#135acd", "icon_width": 8, "spacing": 10, "text": { @@ -137,8 +137,8 @@ "background": "#ffffff", "icon_close": "#555555", "icon_close_active": "#000000", - "icon_conflict": "#f6bc09", - "icon_dirty": "#4287f6", + "icon_conflict": "#f7bf17", + "icon_dirty": "#135acd", "icon_width": 8, "spacing": 10, "text": { @@ -289,7 +289,7 @@ }, "outdated_warning": { "family": "Zed Sans", - "color": "#e5af09", + "color": "#d3a20b", "size": 13 } }, @@ -297,7 +297,7 @@ "height": 34, "background": "#ffffff", "border": { - "color": "#c6c6c6", + "color": "#e3e3e3", "width": 1, "bottom": true }, @@ -327,52 +327,52 @@ "editor": { "text_color": "#2b2b2b", "background": "#ffffff", - "active_line_background": "#e3e3e3", + "active_line_background": "#f1f1f1", "code_actions_indicator": "#717171", - "diff_background_deleted": "#fdd4d4", - "diff_background_inserted": "#befad2", - "document_highlight_read_background": "#e3e3e3", - "document_highlight_write_background": "#e3e3e3", - "error_color": "#f47171", + "diff_background_deleted": "#fcc6c6", + "diff_background_inserted": "#b7f9ce", + "document_highlight_read_background": "#f1f1f1", + "document_highlight_write_background": "#f1f1f1", + "error_color": "#eb2d2d", "gutter_background": "#ffffff", - "gutter_padding_factor": 2.5, - "highlighted_line_background": "#e3e3e3", - "line_number": "#808080", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#f1f1f1", + "line_number": "#aaaaaa", "line_number_active": "#000000", "rename_fade": 0.6, "unnecessary_code_fade": 0.5, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#c5dafc" }, "guest_selections": [ { - "cursor": "#87d116", - "selection": "#dbf9ac" + "cursor": "#79ba16", + "selection": "#dffab5" }, { - "cursor": "#777af4", - "selection": "#d4d5fd" + "cursor": "#484bed", + "selection": "#cdcdfc" }, { - "cursor": "#f98a3d", - "selection": "#fde0cd" + "cursor": "#ee670a", + "selection": "#fcd6bd" }, { - "cursor": "#b671f8", - "selection": "#e9d4fd" + "cursor": "#993bf3", + "selection": "#e4cbfc" }, { - "cursor": "#16ddc7", - "selection": "#b4faf2" + "cursor": "#16d6c1", + "selection": "#b1faf2" }, { - "cursor": "#f58ac0", - "selection": "#fcd4e8" + "cursor": "#ef59a3", + "selection": "#fbc6e1" }, { - "cursor": "#f6bc09", - "selection": "#fceabc" + "cursor": "#f7bf17", + "selection": "#fce9b7" } ], "autocomplete": { @@ -400,13 +400,13 @@ "right": 6, "top": 2 }, - "background": "#f1f1f1" + "background": "#f8f8f8" }, "margin": { "left": -14 }, "match_highlight": { - "color": "#59c3f5", + "color": "#103063", "weight": "normal" }, "selected_item": { @@ -417,7 +417,7 @@ "right": 6, "top": 2 }, - "background": "#e3e3e3" + "background": "#f1f1f1" } }, "diagnostic_header": { @@ -453,7 +453,7 @@ } }, "diagnostic_path_header": { - "background": "#e3e3e3", + "background": "#f1f1f1", "text_scale_factor": 0.857, "filename": { "family": "Zed Mono", @@ -481,12 +481,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#f47171", + "color": "#eb2d2d", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#f47171", + "color": "#eb2d2d", "size": 14, "weight": "bold" } @@ -504,12 +504,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#e5af09", + "color": "#d3a20b", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#e5af09", + "color": "#d3a20b", "size": 14, "weight": "bold" } @@ -527,12 +527,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14, "weight": "bold" } @@ -550,12 +550,12 @@ "message": { "text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14 }, "highlight_text": { "family": "Zed Sans", - "color": "#6099f7", + "color": "#2472f2", "size": 14, "weight": "bold" } @@ -653,7 +653,35 @@ } } }, - "syntax": {} + "syntax": { + "keyword": "#103063", + "function": "#1b9447", + "string": "#bb550e", + "type": "#138a7d", + "number": "#14a898", + "comment": "#555555", + "property": "#134697", + "variant": "#1179a8", + "constant": "#393939", + "title": { + "color": "#1096d3", + "weight": "bold" + }, + "emphasis": "#2472f2", + "emphasis_strong": { + "color": "#2472f2", + "weight": "bold" + }, + "link_uri": { + "color": "#14a898", + "underline": true + }, + "link_text": { + "color": "#ee670a", + "italic": true + }, + "list_marker": "#20b0f2" + } }, "project_diagnostics": { "tab_icon_spacing": 4, @@ -929,8 +957,8 @@ "size": 14 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#c5dafc" }, "border": { "color": "#e3e3e3", @@ -1022,7 +1050,7 @@ "padding": { "left": 8 }, - "background": "#e3e3e3", + "background": "#f1f1f1", "corner_radius": 6 }, "unshared_project": { @@ -1062,7 +1090,7 @@ "padding": { "left": 8 }, - "background": "#e3e3e3", + "background": "#f1f1f1", "corner_radius": 6 } }, @@ -1123,8 +1151,8 @@ "size": 16 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#c5dafc" }, "text": { "family": "Zed Mono", @@ -1177,8 +1205,8 @@ "size": 16 }, "selection": { - "cursor": "#6099f7", - "selection": "#d0e2fd" + "cursor": "#2472f2", + "selection": "#c5dafc" }, "text": { "family": "Zed Mono", @@ -1186,7 +1214,7 @@ "size": 16 }, "border": { - "color": "#fbbdbd", + "color": "#f9a0a0", "width": 1 }, "margin": { diff --git a/styles/styleTree/editor.ts b/styles/styleTree/editor.ts index e760ecec6a57997c48238e0fdeb16d457c2c3e69..23c1e67ac6e6c1dcc75e1d638e760184bfc66e0f 100644 --- a/styles/styleTree/editor.ts +++ b/styles/styleTree/editor.ts @@ -49,7 +49,7 @@ export default function editor(theme: Theme) { documentHighlightWriteBackground: theme.editor.highlight.occurrence.value, errorColor: theme.textColor.error.value, gutterBackground: backgroundColor(theme, 500), - gutterPaddingFactor: 2.5, + gutterPaddingFactor: 3.5, highlightedLineBackground: theme.editor.line.highlighted.value, lineNumber: theme.editor.gutter.primary.value, lineNumberActive: theme.editor.gutter.active.value, @@ -129,7 +129,21 @@ export default function editor(theme: Theme) { invalidInformationDiagnostic: diagnostic(theme, "muted"), invalidWarningDiagnostic: diagnostic(theme, "muted"), syntax: { - - } + keyword: theme.syntax.keyword.color.value, + function: theme.syntax.function.color.value, + string: theme.syntax.string.color.value, + type: theme.syntax.type.color.value, + number: theme.syntax.number.color.value, + comment: theme.syntax.comment.color.value, + property: theme.syntax.property.color.value, + variant: theme.syntax.variant.color.value, + constant: theme.syntax.constant.color.value, + title: { color: theme.syntax.title.color.value, weight: "bold" }, + emphasis: theme.textColor.feature.value, + "emphasis.strong": { color: theme.textColor.feature.value, weight: "bold" }, + link_uri: { color: theme.syntax.linkUrl.color.value, underline: true }, + link_text: { color: theme.syntax.linkText.color.value, italic: true }, + list_marker: theme.syntax.listMarker.color.value, + }, }; } diff --git a/styles/styleTree/workspace.ts b/styles/styleTree/workspace.ts index 4349ba0ab6861080a146e6d25b8be9d6af801d71..030f8edc95e758b574b2df7378acc1bbf498ad3f 100644 --- a/styles/styleTree/workspace.ts +++ b/styles/styleTree/workspace.ts @@ -135,7 +135,7 @@ export default function workspace(theme: Theme) { toolbar: { height: 34, background: backgroundColor(theme, 500), - border: border(theme, "primary", { bottom: true }), + border: border(theme, "secondary", { bottom: true }), itemSpacing: 8, padding: { left: 16, right: 8, top: 4, bottom: 4 }, }, diff --git a/styles/themes/dark.ts b/styles/themes/dark.ts index 3cb3b653b4a6407d197049b0baf1ff72997b02c7..3351d3d3fab34f33e033eb610f701555da34f4b2 100644 --- a/styles/themes/dark.ts +++ b/styles/themes/dark.ts @@ -88,39 +88,39 @@ const iconColor = { const player = { 1: { - baseColor: colors.blue[600], - cursorColor: colors.blue[600], - selectionColor: colors.blue[100], - borderColor: colors.blue[600], + baseColor: colors.blue[500], + cursorColor: colors.blue[500], + selectionColor: colors.blue[800], + borderColor: colors.blue[800], }, 2: { baseColor: colors.lime[500], cursorColor: colors.lime[500], - selectionColor: colors.lime[100], + selectionColor: colors.lime[800], borderColor: colors.lime[500], }, 3: { baseColor: colors.indigo[500], cursorColor: colors.indigo[500], - selectionColor: colors.indigo[100], + selectionColor: colors.indigo[800], borderColor: colors.indigo[500], }, 4: { baseColor: colors.orange[500], cursorColor: colors.orange[500], - selectionColor: colors.orange[100], + selectionColor: colors.orange[800], borderColor: colors.orange[500], }, 5: { baseColor: colors.purple[500], cursorColor: colors.purple[500], - selectionColor: colors.purple[100], + selectionColor: colors.purple[800], borderColor: colors.purple[500], }, 6: { baseColor: colors.teal[400], cursorColor: colors.teal[400], - selectionColor: colors.teal[100], + selectionColor: colors.teal[800], borderColor: colors.teal[400], }, 7: { @@ -151,11 +151,11 @@ const editor = { }, highlight: { selection: player[1].selectionColor, - occurrence: colors.indigo[500], // TODO: Why does indigo[500], indigo[100], and indigo[900] all give me the same color? @kethku - activeOccurrence: colors.indigo[400], // TODO: We don't seem to be using this right now in rust + occurrence: colors.neutral[750], + activeOccurrence: colors.neutral[700], matchingBracket: backgroundColor[500].active, - match: colors.lime[500], - activeMatch: colors.lime[400], + match: colors.sky[900], + activeMatch: colors.sky[800], related: backgroundColor[500].focused, }, gutter: { @@ -166,15 +166,15 @@ const editor = { const syntax: Syntax = { primary: { - color: textColor.primary, + color: colors.neutral[150], weight: fontWeights.normal, }, comment: { - color: colors.lime[200], + color: colors.neutral[300], weight: fontWeights.normal, }, punctuation: { - color: textColor.primary, + color: colors.neutral[200], weight: fontWeights.normal, }, constant: { @@ -182,7 +182,7 @@ const syntax: Syntax = { weight: fontWeights.normal, }, keyword: { - color: colors.sky[400], + color: colors.blue[400], weight: fontWeights.normal, }, function: { @@ -194,19 +194,19 @@ const syntax: Syntax = { weight: fontWeights.normal, }, variant: { - color: colors.teal[300], + color: colors.sky[300], weight: fontWeights.normal, }, property: { - color: colors.sky[300], + color: colors.blue[400], weight: fontWeights.normal, }, enum: { - color: colors.sky[400], + color: colors.orange[500], weight: fontWeights.normal, }, operator: { - color: colors.sky[400], + color: colors.orange[500], weight: fontWeights.normal, }, string: { @@ -214,11 +214,11 @@ const syntax: Syntax = { weight: fontWeights.normal, }, number: { - color: colors.neutral[150], + color: colors.lime[300], weight: fontWeights.normal, }, boolean: { - color: colors.neutral[150], + color: colors.lime[300], weight: fontWeights.normal, }, predictive: { @@ -226,7 +226,7 @@ const syntax: Syntax = { weight: fontWeights.normal, }, title: { - color: colors.sky[500], + color: colors.amber[500], weight: fontWeights.bold, }, emphasis: { diff --git a/styles/themes/light.ts b/styles/themes/light.ts index ee94e18b19869727eae1c973d908ed3202282c77..649fd719a8f75bd47e4c07e8744a4863ae1f5d9f 100644 --- a/styles/themes/light.ts +++ b/styles/themes/light.ts @@ -18,9 +18,9 @@ const backgroundColor = { }, 500: { base: colors.neutral[0], - hovered: colors.neutral[50], - active: colors.neutral[100], - focused: colors.neutral[50], + hovered: colors.neutral[25], + active: colors.neutral[50], + focused: colors.neutral[75], }, ok: { base: colors.green[100], @@ -159,66 +159,66 @@ const editor = { related: colors.neutral[0], }, gutter: { - primary: textColor.muted, + primary: colors.neutral[300], active: textColor.active, }, }; const syntax: Syntax = { primary: { - color: textColor.primary, + color: colors.neutral[750], weight: fontWeights.normal, }, comment: { - color: colors.lime[200], + color: colors.neutral[600], weight: fontWeights.normal, }, punctuation: { - color: textColor.primary, + color: colors.neutral[700], weight: fontWeights.normal, }, constant: { - color: colors.neutral[150], + color: colors.neutral[700], weight: fontWeights.normal, }, keyword: { - color: colors.sky[400], + color: colors.blue[800], weight: fontWeights.normal, }, function: { - color: colors.yellow[200], + color: colors.green[600], weight: fontWeights.normal, }, type: { - color: colors.teal[300], + color: colors.teal[600], weight: fontWeights.normal, }, variant: { - color: colors.teal[300], + color: colors.sky[600], weight: fontWeights.normal, }, property: { - color: colors.sky[300], + color: colors.blue[700], weight: fontWeights.normal, }, enum: { - color: colors.sky[400], + color: colors.orange[600], weight: fontWeights.normal, }, operator: { - color: colors.sky[400], + color: colors.orange[600], weight: fontWeights.normal, }, string: { - color: colors.orange[300], + color: colors.orange[600], weight: fontWeights.normal, }, number: { - color: colors.neutral[150], + color: colors.teal[500], weight: fontWeights.normal, }, boolean: { - color: colors.neutral[150], + color: colors.amber[600], weight: fontWeights.normal, }, predictive: { @@ -238,7 +238,7 @@ const syntax: Syntax = { weight: fontWeights.bold, }, linkUrl: { - color: colors.lime[500], + color: colors.teal[500], weight: fontWeights.normal, // TODO: add underline }, diff --git a/styles/utils/color.ts b/styles/utils/color.ts index 156fc5ba41b2bbf0cfc9dd8080db9bf6cd6c320d..e69d903a431cdef0dc9acdc3f76eb8b535d519f4 100644 --- a/styles/utils/color.ts +++ b/styles/utils/color.ts @@ -17,14 +17,14 @@ export function colorRamp( } else { let hue = Math.round(chroma(color).hsl()[0]); let startColor = chroma.hsl(hue, 0.88, 0.96); - let endColor = chroma.hsl(hue, 0.68, 0.32); + let endColor = chroma.hsl(hue, 0.68, 0.12); scale = chroma .scale([startColor, color, endColor]) .domain([0, 0.5, 1]) .mode("hsl") .gamma(1) - .correctLightness(true) - .padding([0, 0.15]); + // .correctLightness(true) + .padding([0, 0]); } const ramp: ColorRamp = {};