Merge remote-tracking branch 'origin/main' into scrollbars2

This commit is contained in:
Antonio Scandurra 2023-12-11 09:51:43 +01:00
commit 03df63aa00
107 changed files with 13202 additions and 9651 deletions

5
Cargo.lock generated
View file

@ -1154,6 +1154,7 @@ dependencies = [
"gpui2",
"itertools 0.10.5",
"language2",
"outline2",
"project2",
"search2",
"settings2",
@ -1753,7 +1754,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.30.0"
version = "0.30.1"
dependencies = [
"anyhow",
"async-trait",
@ -10511,7 +10512,7 @@ dependencies = [
[[package]]
name = "tree-sitter-vue"
version = "0.0.1"
source = "git+https://github.com/zed-industries/tree-sitter-vue?rev=9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58#9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58"
source = "git+https://github.com/zed-industries/tree-sitter-vue?rev=6608d9d60c386f19d80af7d8132322fa11199c42#6608d9d60c386f19d80af7d8132322fa11199c42"
dependencies = [
"cc",
"tree-sitter",

View file

@ -205,7 +205,7 @@ tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml",
tree-sitter-lua = "0.0.14"
tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" }
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "786689b0562b9799ce53e824cb45a1a2a04dc673"}
tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58"}
tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"}
tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"}
[patch.crates-io]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ use ui::h_stack;
use util::ResultExt;
use workspace::{item::ItemHandle, StatusItemView, Workspace};
actions!(ShowErrorMessage);
actions!(activity_indicator, [ShowErrorMessage]);
const DOWNLOAD_ICON: &str = "icons/download.svg";
const WARNING_ICON: &str = "icons/warning.svg";

View file

@ -12,23 +12,26 @@ use chrono::{DateTime, Local};
use collections::HashMap;
use fs::Fs;
use futures::StreamExt;
use gpui::{actions, AppContext};
use gpui::{actions, AppContext, SharedString};
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::{cmp::Reverse, ffi::OsStr, path::PathBuf, sync::Arc};
use util::paths::CONVERSATIONS_DIR;
actions!(
NewConversation,
Assist,
Split,
CycleMessageRole,
QuoteSelection,
ToggleFocus,
ResetKey,
InlineAssist,
ToggleIncludeConversation,
ToggleRetrieveContext,
assistant,
[
NewConversation,
Assist,
Split,
CycleMessageRole,
QuoteSelection,
ToggleFocus,
ResetKey,
InlineAssist,
ToggleIncludeConversation,
ToggleRetrieveContext,
]
);
#[derive(
@ -47,7 +50,7 @@ struct MessageMetadata {
enum MessageStatus {
Pending,
Done,
Error(Arc<str>),
Error(SharedString),
}
#[derive(Serialize, Deserialize)]

View file

@ -1628,8 +1628,9 @@ impl Conversation {
metadata.status = MessageStatus::Done;
}
Err(error) => {
metadata.status =
MessageStatus::Error(error.to_string().trim().into());
metadata.status = MessageStatus::Error(SharedString::from(
error.to_string().trim().to_string(),
));
}
}
cx.notify();
@ -2273,7 +2274,7 @@ impl ConversationEditor {
Some(
div()
.id("error")
.tooltip(move |cx| Tooltip::text(&error, cx))
.tooltip(move |cx| Tooltip::text(error.clone(), cx))
.child(IconElement::new(Icon::XCircle)),
)
} else {

View file

@ -26,10 +26,13 @@ const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
//todo!(remove CheckThatAutoUpdaterWorks)
actions!(
Check,
DismissErrorMessage,
ViewReleaseNotes,
CheckThatAutoUpdaterWorks
auto_update,
[
Check,
DismissErrorMessage,
ViewReleaseNotes,
CheckThatAutoUpdaterWorks
]
);
#[derive(Serialize)]

View file

@ -19,7 +19,7 @@ search = { package = "search2", path = "../search2" }
settings = { package = "settings2", path = "../settings2" }
theme = { package = "theme2", path = "../theme2" }
workspace = { package = "workspace2", path = "../workspace2" }
# outline = { path = "../outline" }
outline = { package = "outline2", path = "../outline2" }
itertools = "0.10"
[dev-dependencies]

View file

@ -4,7 +4,7 @@ use gpui::{
};
use itertools::Itertools;
use theme::ActiveTheme;
use ui::{prelude::*, ButtonLike, ButtonStyle, Label};
use ui::{prelude::*, ButtonLike, ButtonStyle, Label, Tooltip};
use workspace::{
item::{ItemEvent, ItemHandle},
ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
@ -18,7 +18,7 @@ pub struct Breadcrumbs {
pane_focused: bool,
active_item: Option<Box<dyn ItemHandle>>,
subscription: Option<Subscription>,
_workspace: WeakView<Workspace>,
workspace: WeakView<Workspace>,
}
impl Breadcrumbs {
@ -27,7 +27,7 @@ impl Breadcrumbs {
pane_focused: false,
active_item: Default::default(),
subscription: Default::default(),
_workspace: workspace.weak_handle(),
workspace: workspace.weak_handle(),
}
}
}
@ -66,93 +66,32 @@ impl Render for Breadcrumbs {
ButtonLike::new("toggle outline view")
.style(ButtonStyle::Subtle)
.child(h_stack().gap_1().children(breadcrumbs))
// We disable the button when it is not focused
// due to ... @julia what was the reason again?
// We disable the button when the containing pane is not focused:
// Because right now all the breadcrumb does is open the outline view, which is an
// action which operates on the active editor, clicking the breadcrumbs of another
// editor could cause weirdness. I remember that at one point it actually caused a
// panic weirdly.
//
// It might be possible that with changes around how focus is managed that we
// might be able to update the active editor to the one with the breadcrumbs
// clicked on? That or we could just add a code path for being able to open the
// outline for a specific editor. Long term we'd like for it to be an actual
// breadcrumb bar so that problem goes away
//
// — Julia (https://github.com/zed-industries/zed/pull/3505#pullrequestreview-1766198050)
.disabled(!self.pane_focused)
.on_click(move |_, _cx| {
todo!("outline::toggle");
// this.update(cx, |this, cx| {
// if let Some(workspace) = this.workspace.upgrade() {
// workspace.update(cx, |_workspace, _cx| {
// outline::toggle(workspace, &Default::default(), cx)
// })
// }
// })
// .ok();
}),
.on_click(cx.listener(|breadcrumbs, _, cx| {
if let Some(workspace) = breadcrumbs.workspace.upgrade() {
workspace.update(cx, |workspace, cx| {
outline::toggle(workspace, &outline::Toggle, cx)
})
}
}))
.tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)),
)
}
}
// impl View for Breadcrumbs {
// fn ui_name() -> &'static str {
// "Breadcrumbs"
// }
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
// let active_item = match &self.active_item {
// Some(active_item) => active_item,
// None => return Empty::new().into_any(),
// };
// let not_editor = active_item.downcast::<editor::Editor>().is_none();
// let theme = theme::current(cx).clone();
// let style = &theme.workspace.toolbar.breadcrumbs;
// let breadcrumbs = match active_item.breadcrumbs(&theme, cx) {
// Some(breadcrumbs) => breadcrumbs,
// None => return Empty::new().into_any(),
// }
// .into_iter()
// .map(|breadcrumb| {
// Text::new(
// breadcrumb.text,
// theme.workspace.toolbar.breadcrumbs.default.text.clone(),
// )
// .with_highlights(breadcrumb.highlights.unwrap_or_default())
// .into_any()
// });
// let crumbs = Flex::row()
// .with_children(Itertools::intersperse_with(breadcrumbs, || {
// Label::new(" ", style.default.text.clone()).into_any()
// }))
// .constrained()
// .with_height(theme.workspace.toolbar.breadcrumb_height)
// .contained();
// if not_editor || !self.pane_focused {
// return crumbs
// .with_style(style.default.container)
// .aligned()
// .left()
// .into_any();
// }
// MouseEventHandler::new::<Breadcrumbs, _>(0, cx, |state, _| {
// let style = style.style_for(state);
// crumbs.with_style(style.container)
// })
// .on_click(MouseButton::Left, |_, this, cx| {
// if let Some(workspace) = this.workspace.upgrade(cx) {
// workspace.update(cx, |workspace, cx| {
// outline::toggle(workspace, &Default::default(), cx)
// })
// }
// })
// .with_tooltip::<Breadcrumbs>(
// 0,
// "Show symbol outline".to_owned(),
// Some(Box::new(outline::Toggle)),
// theme.tooltip.clone(),
// cx,
// )
// .aligned()
// .left()
// .into_any()
// }
// }
impl ToolbarItemView for Breadcrumbs {
fn set_active_pane_item(
&mut self,

View file

@ -8,7 +8,8 @@ use collections::{hash_map, HashMap, HashSet};
use db::RELEASE_CHANNEL;
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
use gpui::{
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Task, WeakModel,
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, SharedString, Task,
WeakModel,
};
use rpc::{
proto::{self, ChannelVisibility},
@ -46,7 +47,7 @@ pub struct ChannelStore {
#[derive(Clone, Debug, PartialEq)]
pub struct Channel {
pub id: ChannelId,
pub name: String,
pub name: SharedString,
pub visibility: proto::ChannelVisibility,
pub role: proto::ChannelRole,
pub unseen_note_version: Option<(u64, clock::Global)>,
@ -895,14 +896,16 @@ impl ChannelStore {
.channel_invitations
.binary_search_by_key(&channel.id, |c| c.id)
{
Ok(ix) => Arc::make_mut(&mut self.channel_invitations[ix]).name = channel.name,
Ok(ix) => {
Arc::make_mut(&mut self.channel_invitations[ix]).name = channel.name.into()
}
Err(ix) => self.channel_invitations.insert(
ix,
Arc::new(Channel {
id: channel.id,
visibility: channel.visibility(),
role: channel.role(),
name: channel.name,
name: channel.name.into(),
unseen_note_version: None,
unseen_message_id: None,
parent_path: channel.parent_path,

View file

@ -104,7 +104,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
existing_channel.visibility = channel_proto.visibility();
existing_channel.role = channel_proto.role();
existing_channel.name = channel_proto.name;
existing_channel.name = channel_proto.name.into();
} else {
self.channels_by_id.insert(
channel_proto.id,
@ -112,7 +112,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
id: channel_proto.id,
visibility: channel_proto.visibility(),
role: channel_proto.role(),
name: channel_proto.name,
name: channel_proto.name.into(),
unseen_note_version: None,
unseen_message_id: None,
parent_path: channel_proto.parent_path,
@ -146,11 +146,11 @@ fn channel_path_sorting_key<'a>(
let (parent_path, name) = channels_by_id
.get(&id)
.map_or((&[] as &[_], None), |channel| {
(channel.parent_path.as_slice(), Some(channel.name.as_str()))
(channel.parent_path.as_slice(), Some(channel.name.as_ref()))
});
parent_path
.iter()
.filter_map(|id| Some(channels_by_id.get(id)?.name.as_str()))
.filter_map(|id| Some(channels_by_id.get(id)?.name.as_ref()))
.chain(name)
}

View file

@ -70,7 +70,7 @@ pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894";
pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(100);
pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
actions!(SignIn, SignOut, Reconnect);
actions!(client, [SignIn, SignOut, Reconnect]);
pub fn init_settings(cx: &mut AppContext) {
TelemetrySettings::register(cx);

View file

@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathan@zed.dev>"]
default-run = "collab"
edition = "2021"
name = "collab"
version = "0.30.0"
version = "0.30.1"
publish = false
[[bin]]

View file

@ -116,12 +116,13 @@ struct CreateUserResponse {
#[derive(Debug, Deserialize)]
struct Panic {
version: String,
release_channel: String,
text: String,
}
#[instrument(skip(panic))]
async fn trace_panic(panic: Json<Panic>) -> Result<()> {
tracing::error!(version = %panic.version, text = %panic.text, "panic report");
tracing::error!(version = %panic.version, release_channel = %panic.release_channel, text = %panic.text, "panic report");
Ok(())
}

View file

@ -7,7 +7,7 @@ use call::ActiveCall;
use channel::{ChannelId, ChannelMembership, ChannelStore};
use client::User;
use futures::future::try_join_all;
use gpui::{BackgroundExecutor, Model, TestAppContext};
use gpui::{BackgroundExecutor, Model, SharedString, TestAppContext};
use rpc::{
proto::{self, ChannelRole},
RECEIVE_TIMEOUT,
@ -46,13 +46,13 @@ async fn test_core_channels(
&[
ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Admin,
},
ExpectedChannel {
id: channel_b_id,
name: "channel-b".to_string(),
name: "channel-b".into(),
depth: 1,
role: ChannelRole::Admin,
},
@ -92,7 +92,7 @@ async fn test_core_channels(
cx_b,
&[ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Member,
}],
@ -140,13 +140,13 @@ async fn test_core_channels(
&[
ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
role: ChannelRole::Member,
depth: 0,
},
ExpectedChannel {
id: channel_b_id,
name: "channel-b".to_string(),
name: "channel-b".into(),
role: ChannelRole::Member,
depth: 1,
},
@ -168,19 +168,19 @@ async fn test_core_channels(
&[
ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
role: ChannelRole::Member,
depth: 0,
},
ExpectedChannel {
id: channel_b_id,
name: "channel-b".to_string(),
name: "channel-b".into(),
role: ChannelRole::Member,
depth: 1,
},
ExpectedChannel {
id: channel_c_id,
name: "channel-c".to_string(),
name: "channel-c".into(),
role: ChannelRole::Member,
depth: 2,
},
@ -211,19 +211,19 @@ async fn test_core_channels(
&[
ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Admin,
},
ExpectedChannel {
id: channel_b_id,
name: "channel-b".to_string(),
name: "channel-b".into(),
depth: 1,
role: ChannelRole::Admin,
},
ExpectedChannel {
id: channel_c_id,
name: "channel-c".to_string(),
name: "channel-c".into(),
depth: 2,
role: ChannelRole::Admin,
},
@ -245,7 +245,7 @@ async fn test_core_channels(
cx_a,
&[ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Admin,
}],
@ -255,7 +255,7 @@ async fn test_core_channels(
cx_b,
&[ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Admin,
}],
@ -278,7 +278,7 @@ async fn test_core_channels(
cx_a,
&[ExpectedChannel {
id: channel_a_id,
name: "channel-a".to_string(),
name: "channel-a".into(),
depth: 0,
role: ChannelRole::Admin,
}],
@ -309,7 +309,7 @@ async fn test_core_channels(
cx_a,
&[ExpectedChannel {
id: channel_a_id,
name: "channel-a-renamed".to_string(),
name: "channel-a-renamed".into(),
depth: 0,
role: ChannelRole::Admin,
}],
@ -418,7 +418,7 @@ async fn test_channel_room(
cx_b,
&[ExpectedChannel {
id: zed_id,
name: "zed".to_string(),
name: "zed".into(),
depth: 0,
role: ChannelRole::Member,
}],
@ -680,7 +680,7 @@ async fn test_permissions_update_while_invited(
&[ExpectedChannel {
depth: 0,
id: rust_id,
name: "rust".to_string(),
name: "rust".into(),
role: ChannelRole::Member,
}],
);
@ -708,7 +708,7 @@ async fn test_permissions_update_while_invited(
&[ExpectedChannel {
depth: 0,
id: rust_id,
name: "rust".to_string(),
name: "rust".into(),
role: ChannelRole::Member,
}],
);
@ -747,7 +747,7 @@ async fn test_channel_rename(
&[ExpectedChannel {
depth: 0,
id: rust_id,
name: "rust-archive".to_string(),
name: "rust-archive".into(),
role: ChannelRole::Admin,
}],
);
@ -759,7 +759,7 @@ async fn test_channel_rename(
&[ExpectedChannel {
depth: 0,
id: rust_id,
name: "rust-archive".to_string(),
name: "rust-archive".into(),
role: ChannelRole::Member,
}],
);
@ -888,7 +888,7 @@ async fn test_lost_channel_creation(
&[ExpectedChannel {
depth: 0,
id: channel_id,
name: "x".to_string(),
name: "x".into(),
role: ChannelRole::Member,
}],
);
@ -912,13 +912,13 @@ async fn test_lost_channel_creation(
ExpectedChannel {
depth: 0,
id: channel_id,
name: "x".to_string(),
name: "x".into(),
role: ChannelRole::Admin,
},
ExpectedChannel {
depth: 1,
id: subchannel_id,
name: "subchannel".to_string(),
name: "subchannel".into(),
role: ChannelRole::Admin,
},
],
@ -943,13 +943,13 @@ async fn test_lost_channel_creation(
ExpectedChannel {
depth: 0,
id: channel_id,
name: "x".to_string(),
name: "x".into(),
role: ChannelRole::Member,
},
ExpectedChannel {
depth: 1,
id: subchannel_id,
name: "subchannel".to_string(),
name: "subchannel".into(),
role: ChannelRole::Member,
},
],
@ -1221,13 +1221,13 @@ async fn test_channel_membership_notifications(
ExpectedChannel {
depth: 0,
id: zed_channel,
name: "zed".to_string(),
name: "zed".into(),
role: ChannelRole::Guest,
},
ExpectedChannel {
depth: 1,
id: vim_channel,
name: "vim".to_string(),
name: "vim".into(),
role: ChannelRole::Member,
},
],
@ -1250,13 +1250,13 @@ async fn test_channel_membership_notifications(
ExpectedChannel {
depth: 0,
id: zed_channel,
name: "zed".to_string(),
name: "zed".into(),
role: ChannelRole::Guest,
},
ExpectedChannel {
depth: 1,
id: vim_channel,
name: "vim".to_string(),
name: "vim".into(),
role: ChannelRole::Guest,
},
],
@ -1476,7 +1476,7 @@ async fn test_channel_moving(
struct ExpectedChannel {
depth: usize,
id: ChannelId,
name: String,
name: SharedString,
role: ChannelRole,
}
@ -1515,7 +1515,7 @@ fn assert_channels(
.ordered_channels()
.map(|(depth, channel)| ExpectedChannel {
depth,
name: channel.name.clone(),
name: channel.name.clone().into(),
id: channel.id,
role: channel.role,
})

View file

@ -3,7 +3,7 @@ use crate::db::ChannelRole;
use super::{run_randomized_test, RandomizedTest, TestClient, TestError, TestServer, UserTestPlan};
use anyhow::Result;
use async_trait::async_trait;
use gpui::{BackgroundExecutor, TestAppContext};
use gpui::{BackgroundExecutor, SharedString, TestAppContext};
use rand::prelude::*;
use serde_derive::{Deserialize, Serialize};
use std::{
@ -30,13 +30,13 @@ struct RandomChannelBufferTest;
#[derive(Clone, Serialize, Deserialize)]
enum ChannelBufferOperation {
JoinChannelNotes {
channel_name: String,
channel_name: SharedString,
},
LeaveChannelNotes {
channel_name: String,
channel_name: SharedString,
},
EditChannelNotes {
channel_name: String,
channel_name: SharedString,
edits: Vec<(Range<usize>, Arc<str>)>,
},
Noop,

View file

@ -26,7 +26,7 @@ use workspace::{
ItemNavHistory, Pane, SaveIntent, ViewId, Workspace, WorkspaceId,
};
actions!(Deploy);
actions!(collab, [Deploy]);
pub fn init(cx: &mut AppContext) {
register_followable_item::<ChannelView>(cx)

File diff suppressed because it is too large Load diff

View file

@ -3,13 +3,14 @@ use client::UserId;
use collections::HashMap;
use editor::{AnchorRangeExt, Editor};
use gpui::{
elements::ChildView, AnyElement, AsyncAppContext, Element, Entity, ModelHandle, Task, View,
ViewContext, ViewHandle, WeakViewHandle,
AnyView, AsyncWindowContext, FocusableView, Model, Render, SharedString, Task, View,
ViewContext, WeakView,
};
use language::{language_settings::SoftWrap, Buffer, BufferSnapshot, LanguageRegistry};
use lazy_static::lazy_static;
use project::search::SearchQuery;
use std::{sync::Arc, time::Duration};
use workspace::item::ItemHandle;
const MENTIONS_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(50);
@ -19,8 +20,8 @@ lazy_static! {
}
pub struct MessageEditor {
pub editor: ViewHandle<Editor>,
channel_store: ModelHandle<ChannelStore>,
pub editor: View<Editor>,
channel_store: Model<ChannelStore>,
users: HashMap<String, UserId>,
mentions: Vec<UserId>,
mentions_task: Option<Task<()>>,
@ -30,8 +31,8 @@ pub struct MessageEditor {
impl MessageEditor {
pub fn new(
language_registry: Arc<LanguageRegistry>,
channel_store: ModelHandle<ChannelStore>,
editor: ViewHandle<Editor>,
channel_store: Model<ChannelStore>,
editor: View<Editor>,
cx: &mut ViewContext<Self>,
) -> Self {
editor.update(cx, |editor, cx| {
@ -48,15 +49,13 @@ impl MessageEditor {
cx.subscribe(&buffer, Self::on_buffer_event).detach();
let markdown = language_registry.language_for_name("Markdown");
cx.app_context()
.spawn(|mut cx| async move {
let markdown = markdown.await?;
buffer.update(&mut cx, |buffer, cx| {
buffer.set_language(Some(markdown), cx)
});
anyhow::Ok(())
cx.spawn(|_, mut cx| async move {
let markdown = markdown.await?;
buffer.update(&mut cx, |buffer, cx| {
buffer.set_language(Some(markdown), cx)
})
.detach_and_log_err(cx);
})
.detach_and_log_err(cx);
Self {
editor,
@ -71,7 +70,7 @@ impl MessageEditor {
pub fn set_channel(
&mut self,
channel_id: u64,
channel_name: Option<String>,
channel_name: Option<SharedString>,
cx: &mut ViewContext<Self>,
) {
self.editor.update(cx, |editor, cx| {
@ -132,26 +131,28 @@ impl MessageEditor {
fn on_buffer_event(
&mut self,
buffer: ModelHandle<Buffer>,
buffer: Model<Buffer>,
event: &language::Event,
cx: &mut ViewContext<Self>,
) {
if let language::Event::Reparsed | language::Event::Edited = event {
let buffer = buffer.read(cx).snapshot();
self.mentions_task = Some(cx.spawn(|this, cx| async move {
cx.background().timer(MENTIONS_DEBOUNCE_INTERVAL).await;
cx.background_executor()
.timer(MENTIONS_DEBOUNCE_INTERVAL)
.await;
Self::find_mentions(this, buffer, cx).await;
}));
}
}
async fn find_mentions(
this: WeakViewHandle<MessageEditor>,
this: WeakView<MessageEditor>,
buffer: BufferSnapshot,
mut cx: AsyncAppContext,
mut cx: AsyncWindowContext,
) {
let (buffer, ranges) = cx
.background()
.background_executor()
.spawn(async move {
let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
(buffer, ranges)
@ -180,11 +181,7 @@ impl MessageEditor {
}
editor.clear_highlights::<Self>(cx);
editor.highlight_text::<Self>(
anchor_ranges,
theme::current(cx).chat_panel.rich_text.mention_highlight,
cx,
)
editor.highlight_text::<Self>(anchor_ranges, gpui::red().into(), cx)
});
this.mentions = mentioned_user_ids;
@ -192,21 +189,17 @@ impl MessageEditor {
})
.ok();
}
}
impl Entity for MessageEditor {
type Event = ();
}
impl View for MessageEditor {
fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self> {
ChildView::new(&self.editor, cx).into_any()
pub(crate) fn focus_handle(&self, cx: &gpui::AppContext) -> gpui::FocusHandle {
self.editor.read(cx).focus_handle(cx)
}
}
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
if cx.is_self_focused() {
cx.focus(&self.editor);
}
impl Render for MessageEditor {
type Element = AnyView;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
self.editor.to_any()
}
}
@ -214,7 +207,7 @@ impl View for MessageEditor {
mod tests {
use super::*;
use client::{Client, User, UserStore};
use gpui::{TestAppContext, WindowHandle};
use gpui::{Context as _, TestAppContext, VisualContext as _};
use language::{Language, LanguageConfig};
use rpc::proto;
use settings::SettingsStore;
@ -222,8 +215,17 @@ mod tests {
#[gpui::test]
async fn test_message_editor(cx: &mut TestAppContext) {
let editor = init_test(cx);
let editor = editor.root(cx);
let language_registry = init_test(cx);
let (editor, cx) = cx.add_window_view(|cx| {
MessageEditor::new(
language_registry,
ChannelStore::global(cx),
cx.build_view(|cx| Editor::auto_height(4, cx)),
cx,
)
});
cx.executor().run_until_parked();
editor.update(cx, |editor, cx| {
editor.set_members(
@ -255,7 +257,7 @@ mod tests {
});
});
cx.foreground().advance_clock(MENTIONS_DEBOUNCE_INTERVAL);
cx.executor().advance_clock(MENTIONS_DEBOUNCE_INTERVAL);
editor.update(cx, |editor, cx| {
let (text, ranges) = marked_text_ranges("Hello, «@a-b»! Have you met «@C_D»?", false);
@ -269,15 +271,14 @@ mod tests {
});
}
fn init_test(cx: &mut TestAppContext) -> WindowHandle<MessageEditor> {
cx.foreground().forbid_parking();
fn init_test(cx: &mut TestAppContext) -> Arc<LanguageRegistry> {
cx.update(|cx| {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
cx.set_global(SettingsStore::test(cx));
theme::init((), cx);
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
let settings = SettingsStore::test(cx);
cx.set_global(settings);
theme::init(theme::LoadThemes::JustBase, cx);
language::init(cx);
editor::init(cx);
client::init(&client, cx);
@ -292,16 +293,6 @@ mod tests {
},
Some(tree_sitter_markdown::language()),
)));
let editor = cx.add_window(|cx| {
MessageEditor::new(
language_registry,
ChannelStore::global(cx),
cx.add_view(|cx| Editor::auto_height(4, None, cx)),
cx,
)
});
cx.foreground().run_until_parked();
editor
language_registry
}
}

View file

@ -92,7 +92,7 @@ use theme::{ActiveTheme, ThemeSettings};
// channel_id: ChannelId,
// }
#[derive(Action, PartialEq, Debug, Clone, Serialize, Deserialize)]
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct OpenChannelNotes {
pub channel_id: ChannelId,
}
@ -122,15 +122,20 @@ pub struct OpenChannelNotes {
// to: ChannelId,
// }
impl_actions!(collab_panel, [OpenChannelNotes]);
actions!(
ToggleFocus,
Remove,
Secondary,
CollapseSelectedChannel,
ExpandSelectedChannel,
StartMoveChannel,
MoveSelected,
InsertSpace,
collab_panel,
[
ToggleFocus,
Remove,
Secondary,
CollapseSelectedChannel,
ExpandSelectedChannel,
StartMoveChannel,
MoveSelected,
InsertSpace,
]
);
// impl_actions!(
@ -169,12 +174,12 @@ use editor::Editor;
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
actions, canvas, div, img, overlay, point, prelude::*, px, rems, serde_json, size, Action,
AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter,
FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement, Length, Model,
MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render, RenderOnce,
ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View, ViewContext,
VisualContext, WeakView,
actions, canvas, div, img, impl_actions, overlay, point, prelude::*, px, rems, serde_json,
size, Action, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div,
EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement,
Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render,
RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View,
ViewContext, VisualContext, WeakView,
};
use project::{Fs, Project};
use serde_derive::{Deserialize, Serialize};
@ -192,6 +197,7 @@ use workspace::{
};
use crate::channel_view::ChannelView;
use crate::chat_panel::ChatPanel;
use crate::{face_pile::FacePile, CollaborationPanelSettings};
use self::channel_modal::ChannelModal;
@ -852,7 +858,7 @@ impl CollabPanel {
.extend(channel_store.ordered_channels().enumerate().map(
|(ix, (_, channel))| StringMatchCandidate {
id: ix,
string: channel.name.clone(),
string: channel.name.clone().into(),
char_bag: channel.name.chars().collect(),
},
));
@ -2102,14 +2108,13 @@ impl CollabPanel {
};
cx.window_context().defer(move |cx| {
workspace.update(cx, |workspace, cx| {
todo!();
// if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
// panel.update(cx, |panel, cx| {
// panel
// .select_channel(channel_id, None, cx)
// .detach_and_log_err(cx);
// });
// }
if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
panel.update(cx, |panel, cx| {
panel
.select_channel(channel_id, None, cx)
.detach_and_log_err(cx);
});
}
});
});
}
@ -2262,7 +2267,7 @@ impl CollabPanel {
}
};
Some(channel.name.as_str())
Some(channel.name.as_ref())
});
if let Some(name) = channel_name {
@ -2603,9 +2608,14 @@ impl CollabPanel {
Color::Default
} else {
Color::Muted
})
.on_click(cx.listener(move |this, _, cx| {
this.join_channel_chat(channel_id, cx)
}))
.tooltip(|cx| {
Tooltip::text("Open channel chat", cx)
}),
)
.tooltip(|cx| Tooltip::text("Open channel chat", cx)),
),
)
.child(
div()

View file

@ -13,12 +13,16 @@ use picker::{Picker, PickerDelegate};
use std::sync::Arc;
use ui::prelude::*;
use util::TryFutureExt;
use workspace::ModalView;
actions!(
SelectNextControl,
ToggleMode,
ToggleMemberAdmin,
RemoveMember
channel_modal,
[
SelectNextControl,
ToggleMode,
ToggleMemberAdmin,
RemoveMember
]
);
// pub fn init(cx: &mut AppContext) {
@ -140,6 +144,7 @@ impl ChannelModal {
}
impl EventEmitter<DismissEvent> for ChannelModal {}
impl ModalView for ChannelModal {}
impl FocusableView for ChannelModal {
fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {

View file

@ -9,6 +9,7 @@ use std::sync::Arc;
use theme::ActiveTheme as _;
use ui::prelude::*;
use util::{ResultExt as _, TryFutureExt};
use workspace::ModalView;
pub fn init(cx: &mut AppContext) {
//Picker::<ContactFinderDelegate>::init(cx);
@ -95,6 +96,7 @@ pub struct ContactFinderDelegate {
}
impl EventEmitter<DismissEvent> for ContactFinder {}
impl ModalView for ContactFinder {}
impl FocusableView for ContactFinder {
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {

View file

@ -20,11 +20,14 @@ const MAX_PROJECT_NAME_LENGTH: usize = 40;
const MAX_BRANCH_NAME_LENGTH: usize = 40;
actions!(
ShareProject,
UnshareProject,
ToggleUserMenu,
ToggleProjectMenu,
SwitchBranch
collab,
[
ShareProject,
UnshareProject,
ToggleUserMenu,
ToggleProjectMenu,
SwitchBranch
]
);
pub fn init(cx: &mut AppContext) {

View file

@ -12,6 +12,7 @@ use std::{rc::Rc, sync::Arc};
use call::{report_call_event_for_room, ActiveCall, Room};
pub use collab_panel::CollabPanel;
pub use collab_titlebar_item::CollabTitlebarItem;
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt};
use gpui::{
actions, point, AppContext, GlobalPixels, Pixels, PlatformDisplay, Size, Task, WindowBounds,
WindowKind, WindowOptions,
@ -23,7 +24,10 @@ use settings::Settings;
use util::ResultExt;
use workspace::AppState;
actions!(ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall);
actions!(
collab,
[ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
);
pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
CollaborationPanelSettings::register(cx);
@ -34,7 +38,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
collab_titlebar_item::init(cx);
collab_panel::init(cx);
channel_view::init(cx);
// chat_panel::init(cx);
chat_panel::init(cx);
notifications::init(&app_state, cx);
// cx.add_global_action(toggle_screen_sharing);
@ -157,6 +161,6 @@ fn notification_window_options(
// .into_any()
// }
// fn is_channels_feature_enabled(cx: &gpui::WindowContext<'_>) -> bool {
// cx.is_staff() || cx.has_flag::<ChannelsAlpha>()
// }
fn is_channels_feature_enabled(cx: &gpui::WindowContext<'_>) -> bool {
cx.is_staff() || cx.has_flag::<ChannelsAlpha>()
}

View file

@ -7,7 +7,7 @@ use collections::{CommandPaletteFilter, HashMap};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
actions, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
Keystroke, ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
};
use picker::{Picker, PickerDelegate};
@ -16,16 +16,18 @@ use util::{
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
ResultExt,
};
use workspace::Workspace;
use workspace::{ModalView, Workspace};
use zed_actions::OpenZedURL;
actions!(Toggle);
actions!(command_palette, [Toggle]);
pub fn init(cx: &mut AppContext) {
cx.set_global(HitCounts::default());
cx.observe_new_views(CommandPalette::register).detach();
}
impl ModalView for CommandPalette {}
pub struct CommandPalette {
picker: View<Picker<CommandPaletteDelegate>>,
}
@ -47,7 +49,7 @@ impl CommandPalette {
.available_actions()
.into_iter()
.filter_map(|action| {
let name = gpui::remove_the_2(action.name());
let name = action.name();
let namespace = name.split("::").next().unwrap_or("malformed action name");
if filter.is_some_and(|f| {
f.hidden_namespaces.contains(namespace)
@ -59,7 +61,6 @@ impl CommandPalette {
Some(Command {
name: humanize_action_name(&name),
action,
keystrokes: vec![], // todo!()
})
})
.collect();
@ -108,7 +109,6 @@ pub struct CommandPaletteDelegate {
struct Command {
name: String,
action: Box<dyn Action>,
keystrokes: Vec<Keystroke>,
}
impl Clone for Command {
@ -116,7 +116,6 @@ impl Clone for Command {
Self {
name: self.name.clone(),
action: self.action.boxed_clone(),
keystrokes: self.keystrokes.clone(),
}
}
}
@ -227,6 +226,7 @@ impl PickerDelegate for CommandPaletteDelegate {
})
}
}
if let Some(CommandInterceptResult {
action,
string,
@ -242,7 +242,6 @@ impl PickerDelegate for CommandPaletteDelegate {
commands.push(Command {
name: string.clone(),
action,
keystrokes: vec![],
});
matches.insert(
0,
@ -254,6 +253,7 @@ impl PickerDelegate for CommandPaletteDelegate {
},
)
}
picker
.update(&mut cx, |picker, _| {
let delegate = &mut picker.delegate;
@ -283,6 +283,8 @@ impl PickerDelegate for CommandPaletteDelegate {
}
let action_ix = self.matches[self.selected_ix].candidate_id;
let command = self.commands.swap_remove(action_ix);
self.matches.clear();
self.commands.clear();
cx.update_global(|hit_counts: &mut HitCounts, _| {
*hit_counts.0.entry(command.name).or_default() += 1;
});
@ -298,13 +300,8 @@ impl PickerDelegate for CommandPaletteDelegate {
selected: bool,
cx: &mut ViewContext<Picker<Self>>,
) -> Option<Self::ListItem> {
let Some(r#match) = self.matches.get(ix) else {
return None;
};
let Some(command) = self.commands.get(r#match.candidate_id) else {
return None;
};
let r#match = self.matches.get(ix)?;
let command = self.commands.get(r#match.candidate_id)?;
Some(
ListItem::new(ix).inset(true).selected(selected).child(
h_stack()
@ -352,8 +349,7 @@ impl std::fmt::Debug for Command {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Command")
.field("name", &self.name)
.field("keystrokes", &self.keystrokes)
.finish()
.finish_non_exhaustive()
}
}

View file

@ -34,12 +34,15 @@ use util::{
};
actions!(
Suggest,
NextSuggestion,
PreviousSuggestion,
Reinstall,
SignIn,
SignOut
copilot,
[
Suggest,
NextSuggestion,
PreviousSuggestion,
Reinstall,
SignIn,
SignOut
]
);
pub fn init(

View file

@ -43,7 +43,7 @@ use workspace::{
ItemNavHistory, Pane, ToolbarItemLocation, Workspace,
};
actions!(Deploy, ToggleWarnings);
actions!(diagnostics, [Deploy, ToggleWarnings]);
const CONTEXT_LINE_COUNT: u32 = 1;

View file

@ -39,8 +39,8 @@ use futures::FutureExt;
use fuzzy::{StringMatch, StringMatchCandidate};
use git::diff_hunk_to_display;
use gpui::{
actions, div, point, prelude::*, px, relative, rems, size, uniform_list, Action, AnyElement,
AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
actions, div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action,
AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
DispatchPhase, Div, ElementId, EventEmitter, FocusHandle, FocusableView, FontFeatures,
FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model,
MouseButton, ParentElement, Pixels, Render, RenderOnce, SharedString, Styled, StyledText,
@ -185,82 +185,101 @@ pub fn render_parsed_markdown(
})
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectNext {
#[serde(default)]
pub replace_newest: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectPrevious {
#[serde(default)]
pub replace_newest: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectAllMatches {
#[serde(default)]
pub replace_newest: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectToBeginningOfLine {
#[serde(default)]
stop_at_soft_wraps: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct MovePageUp {
#[serde(default)]
center_cursor: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct MovePageDown {
#[serde(default)]
center_cursor: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct SelectToEndOfLine {
#[serde(default)]
stop_at_soft_wraps: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ToggleCodeActions {
#[serde(default)]
pub deployed_from_indicator: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ConfirmCompletion {
#[serde(default)]
pub item_ix: Option<usize>,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ConfirmCodeAction {
#[serde(default)]
pub item_ix: Option<usize>,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ToggleComments {
#[serde(default)]
pub advance_downwards: bool,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct FoldAt {
pub buffer_row: u32,
}
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct UnfoldAt {
pub buffer_row: u32,
}
impl_actions!(
editor,
[
SelectNext,
SelectPrevious,
SelectAllMatches,
SelectToBeginningOfLine,
MovePageUp,
MovePageDown,
SelectToEndOfLine,
ToggleCodeActions,
ConfirmCompletion,
ConfirmCodeAction,
ToggleComments,
FoldAt,
UnfoldAt
]
);
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum InlayId {
Suggestion(usize),
@ -277,121 +296,124 @@ impl InlayId {
}
actions!(
AddSelectionAbove,
AddSelectionBelow,
Backspace,
Cancel,
ConfirmRename,
ContextMenuFirst,
ContextMenuLast,
ContextMenuNext,
ContextMenuPrev,
ConvertToKebabCase,
ConvertToLowerCamelCase,
ConvertToLowerCase,
ConvertToSnakeCase,
ConvertToTitleCase,
ConvertToUpperCamelCase,
ConvertToUpperCase,
Copy,
CopyHighlightJson,
CopyPath,
CopyRelativePath,
Cut,
CutToEndOfLine,
Delete,
DeleteLine,
DeleteToBeginningOfLine,
DeleteToEndOfLine,
DeleteToNextSubwordEnd,
DeleteToNextWordEnd,
DeleteToPreviousSubwordStart,
DeleteToPreviousWordStart,
DuplicateLine,
FindAllReferences,
Fold,
FoldSelectedRanges,
Format,
GoToDefinition,
GoToDefinitionSplit,
GoToDiagnostic,
GoToHunk,
GoToPrevDiagnostic,
GoToPrevHunk,
GoToTypeDefinition,
GoToTypeDefinitionSplit,
HalfPageDown,
HalfPageUp,
Hover,
Indent,
JoinLines,
LineDown,
LineUp,
MoveDown,
MoveLeft,
MoveLineDown,
MoveLineUp,
MoveRight,
MoveToBeginning,
MoveToBeginningOfLine,
MoveToEnclosingBracket,
MoveToEnd,
MoveToEndOfLine,
MoveToEndOfParagraph,
MoveToNextSubwordEnd,
MoveToNextWordEnd,
MoveToPreviousSubwordStart,
MoveToPreviousWordStart,
MoveToStartOfParagraph,
MoveUp,
Newline,
NewlineAbove,
NewlineBelow,
NextScreen,
OpenExcerpts,
Outdent,
PageDown,
PageUp,
Paste,
Redo,
RedoSelection,
Rename,
RestartLanguageServer,
RevealInFinder,
ReverseLines,
ScrollCursorBottom,
ScrollCursorCenter,
ScrollCursorTop,
SelectAll,
SelectDown,
SelectLargerSyntaxNode,
SelectLeft,
SelectLine,
SelectRight,
SelectSmallerSyntaxNode,
SelectToBeginning,
SelectToEnd,
SelectToEndOfParagraph,
SelectToNextSubwordEnd,
SelectToNextWordEnd,
SelectToPreviousSubwordStart,
SelectToPreviousWordStart,
SelectToStartOfParagraph,
SelectUp,
ShowCharacterPalette,
ShowCompletions,
ShuffleLines,
SortLinesCaseInsensitive,
SortLinesCaseSensitive,
SplitSelectionIntoLines,
Tab,
TabPrev,
ToggleInlayHints,
ToggleSoftWrap,
Transpose,
Undo,
UndoSelection,
UnfoldLines,
editor,
[
AddSelectionAbove,
AddSelectionBelow,
Backspace,
Cancel,
ConfirmRename,
ContextMenuFirst,
ContextMenuLast,
ContextMenuNext,
ContextMenuPrev,
ConvertToKebabCase,
ConvertToLowerCamelCase,
ConvertToLowerCase,
ConvertToSnakeCase,
ConvertToTitleCase,
ConvertToUpperCamelCase,
ConvertToUpperCase,
Copy,
CopyHighlightJson,
CopyPath,
CopyRelativePath,
Cut,
CutToEndOfLine,
Delete,
DeleteLine,
DeleteToBeginningOfLine,
DeleteToEndOfLine,
DeleteToNextSubwordEnd,
DeleteToNextWordEnd,
DeleteToPreviousSubwordStart,
DeleteToPreviousWordStart,
DuplicateLine,
FindAllReferences,
Fold,
FoldSelectedRanges,
Format,
GoToDefinition,
GoToDefinitionSplit,
GoToDiagnostic,
GoToHunk,
GoToPrevDiagnostic,
GoToPrevHunk,
GoToTypeDefinition,
GoToTypeDefinitionSplit,
HalfPageDown,
HalfPageUp,
Hover,
Indent,
JoinLines,
LineDown,
LineUp,
MoveDown,
MoveLeft,
MoveLineDown,
MoveLineUp,
MoveRight,
MoveToBeginning,
MoveToBeginningOfLine,
MoveToEnclosingBracket,
MoveToEnd,
MoveToEndOfLine,
MoveToEndOfParagraph,
MoveToNextSubwordEnd,
MoveToNextWordEnd,
MoveToPreviousSubwordStart,
MoveToPreviousWordStart,
MoveToStartOfParagraph,
MoveUp,
Newline,
NewlineAbove,
NewlineBelow,
NextScreen,
OpenExcerpts,
Outdent,
PageDown,
PageUp,
Paste,
Redo,
RedoSelection,
Rename,
RestartLanguageServer,
RevealInFinder,
ReverseLines,
ScrollCursorBottom,
ScrollCursorCenter,
ScrollCursorTop,
SelectAll,
SelectDown,
SelectLargerSyntaxNode,
SelectLeft,
SelectLine,
SelectRight,
SelectSmallerSyntaxNode,
SelectToBeginning,
SelectToEnd,
SelectToEndOfParagraph,
SelectToNextSubwordEnd,
SelectToNextWordEnd,
SelectToPreviousSubwordStart,
SelectToPreviousWordStart,
SelectToStartOfParagraph,
SelectUp,
ShowCharacterPalette,
ShowCompletions,
ShuffleLines,
SortLinesCaseInsensitive,
SortLinesCaseSensitive,
SplitSelectionIntoLines,
Tab,
TabPrev,
ToggleInlayHints,
ToggleSoftWrap,
Transpose,
Undo,
UndoSelection,
UnfoldLines,
]
);
enum DocumentHighlightRead {}

View file

@ -750,44 +750,47 @@ impl EditorElement {
}
}
for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() {
if let Some(mut fold_indicator) = fold_indicator {
let mut fold_indicator = fold_indicator.into_any_element();
cx.with_z_index(1, |cx| {
for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() {
if let Some(mut fold_indicator) = fold_indicator {
let mut fold_indicator = fold_indicator.into_any_element();
let available_space = size(
AvailableSpace::MinContent,
AvailableSpace::Definite(line_height * 0.55),
);
let fold_indicator_size = fold_indicator.measure(available_space, cx);
let position = point(
bounds.size.width - layout.gutter_padding,
ix as f32 * line_height - (scroll_top % line_height),
);
let centering_offset = point(
(layout.gutter_padding + layout.gutter_margin - fold_indicator_size.width)
/ 2.,
(line_height - fold_indicator_size.height) / 2.,
);
let origin = bounds.origin + position + centering_offset;
fold_indicator.draw(origin, available_space, cx);
}
}
if let Some(indicator) = layout.code_actions_indicator.take() {
let mut button = indicator.button.into_any_element();
let available_space = size(
AvailableSpace::MinContent,
AvailableSpace::Definite(line_height * 0.55),
AvailableSpace::Definite(line_height),
);
let fold_indicator_size = fold_indicator.measure(available_space, cx);
let indicator_size = button.measure(available_space, cx);
let position = point(
bounds.size.width - layout.gutter_padding,
ix as f32 * line_height - (scroll_top % line_height),
);
let centering_offset = point(
(layout.gutter_padding + layout.gutter_margin - fold_indicator_size.width) / 2.,
(line_height - fold_indicator_size.height) / 2.,
);
let origin = bounds.origin + position + centering_offset;
fold_indicator.draw(origin, available_space, cx);
let mut x = Pixels::ZERO;
let mut y = indicator.row as f32 * line_height - scroll_top;
// Center indicator.
x += ((layout.gutter_padding + layout.gutter_margin) - indicator_size.width) / 2.;
y += (line_height - indicator_size.height) / 2.;
button.draw(bounds.origin + point(x, y), available_space, cx);
}
}
if let Some(indicator) = layout.code_actions_indicator.take() {
let mut button = indicator.button.into_any_element();
let available_space = size(
AvailableSpace::MinContent,
AvailableSpace::Definite(line_height),
);
let indicator_size = button.measure(available_space, cx);
let mut x = Pixels::ZERO;
let mut y = indicator.row as f32 * line_height - scroll_top;
// Center indicator.
x += ((layout.gutter_padding + layout.gutter_margin) - indicator_size.width) / 2.;
y += (line_height - indicator_size.height) / 2.;
button.draw(bounds.origin + point(x, y), available_space, cx);
}
});
}
fn paint_diff_hunks(bounds: Bounds<Pixels>, layout: &LayoutState, cx: &mut WindowContext) {
@ -825,8 +828,8 @@ impl EditorElement {
};
let color = match status {
DiffHunkStatus::Added => gpui::green(), // todo!("use the appropriate color")
DiffHunkStatus::Modified => gpui::yellow(), // todo!("use the appropriate color")
DiffHunkStatus::Added => cx.theme().status().created,
DiffHunkStatus::Modified => cx.theme().status().modified,
//TODO: This rendering is entirely a horrible hack
DiffHunkStatus::Removed => {
@ -843,7 +846,7 @@ impl EditorElement {
cx.paint_quad(
highlight_bounds,
Corners::all(1. * line_height),
gpui::red(), // todo!("use the right color")
cx.theme().status().deleted,
Edges::default(),
transparent_black(),
);

View file

@ -26,7 +26,7 @@ pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
pub const MIN_POPOVER_LINE_HEIGHT: Pixels = px(4.);
pub const HOVER_POPOVER_GAP: Pixels = px(10.);
actions!(Hover);
actions!(editor, [Hover]);
/// Bindable action which uses the most recent selection head to trigger a hover
pub fn hover(editor: &mut Editor, _: &Hover, cx: &mut ViewContext<Editor>) {

View file

@ -32,7 +32,7 @@ impl Render for DeployFeedbackButton {
IconButton::new("give-feedback", Icon::Envelope)
.style(ui::ButtonStyle::Subtle)
.selected(is_open)
.tooltip(|cx| Tooltip::text("Give Feedback", cx))
.tooltip(|cx| Tooltip::text("Share Feedback", cx))
.on_click(|_, cx| {
cx.dispatch_action(Box::new(GiveFeedback));
})

View file

@ -5,15 +5,18 @@ use workspace::Workspace;
pub mod deploy_feedback_button;
pub mod feedback_modal;
actions!(GiveFeedback, SubmitFeedback);
actions!(feedback, [GiveFeedback, SubmitFeedback]);
mod system_specs;
actions!(
CopySystemSpecsIntoClipboard,
FileBugReport,
RequestFeature,
OpenZedCommunityRepo
zed,
[
CopySystemSpecsIntoClipboard,
FileBugReport,
RequestFeature,
OpenZedCommunityRepo
]
);
pub fn init(cx: &mut AppContext) {

View file

@ -1,28 +1,38 @@
use std::{ops::RangeInclusive, sync::Arc};
use anyhow::bail;
use anyhow::{anyhow, bail};
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
use db::kvp::KEY_VALUE_STORE;
use editor::{Editor, EditorEvent};
use futures::AsyncReadExt;
use gpui::{
div, red, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle,
FocusableView, Model, PromptLevel, Render, Task, View, ViewContext,
div, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
Model, PromptLevel, Render, Task, View, ViewContext,
};
use isahc::Request;
use language::Buffer;
use project::Project;
use regex::Regex;
use serde_derive::Serialize;
use ui::{prelude::*, Button, ButtonStyle, Label, Tooltip};
use ui::{prelude::*, Button, ButtonStyle, IconPosition, Tooltip};
use util::ResultExt;
use workspace::Workspace;
use workspace::{ModalView, Workspace};
use crate::{system_specs::SystemSpecs, GiveFeedback, OpenZedCommunityRepo};
// For UI testing purposes
const SEND_SUCCESS_IN_DEV_MODE: bool = true;
// Temporary, until tests are in place
#[cfg(debug_assertions)]
const DEV_MODE: bool = true;
#[cfg(not(debug_assertions))]
const DEV_MODE: bool = false;
const DATABASE_KEY_NAME: &str = "email_address";
const EMAIL_REGEX: &str = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b";
const FEEDBACK_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
const FEEDBACK_CHAR_LIMIT: RangeInclusive<i32> = 10..=5000;
const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
"Feedback failed to submit, see error log for details.";
@ -41,8 +51,9 @@ pub struct FeedbackModal {
system_specs: SystemSpecs,
feedback_editor: View<Editor>,
email_address_editor: View<Editor>,
character_count: usize,
pending_submission: bool,
awaiting_submission: bool,
user_submitted: bool,
character_count: i32,
}
impl FocusableView for FeedbackModal {
@ -52,6 +63,25 @@ impl FocusableView for FeedbackModal {
}
impl EventEmitter<DismissEvent> for FeedbackModal {}
impl ModalView for FeedbackModal {
fn dismiss(&mut self, cx: &mut ViewContext<Self>) -> Task<bool> {
if self.user_submitted {
self.set_user_submitted(false, cx);
return cx.spawn(|_, _| async { true });
}
let has_feedback = self.feedback_editor.read(cx).text_option(cx).is_some();
if !has_feedback {
return cx.spawn(|_, _| async { true });
}
let answer = cx.prompt(PromptLevel::Info, "Discard feedback?", &["Yes", "No"]);
cx.spawn(|_, _| async { answer.await.ok() == Some(0) })
}
}
impl FeedbackModal {
pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
let _handle = cx.view().downgrade();
@ -104,6 +134,11 @@ impl FeedbackModal {
let feedback_editor = cx.build_view(|cx| {
let mut editor = Editor::for_buffer(buffer, Some(project.clone()), cx);
editor.set_placeholder_text(
"You can use markdown to organize your feedback wiht add code and links, or organize feedback.",
cx,
);
// editor.set_show_gutter(false, cx);
editor.set_vertical_scroll_margin(5, cx);
editor
});
@ -119,7 +154,7 @@ impl FeedbackModal {
.as_singleton()
.expect("Feedback editor is never a multi-buffer")
.read(cx)
.len();
.len() as i32;
cx.notify();
}
_ => {}
@ -131,7 +166,8 @@ impl FeedbackModal {
system_specs: system_specs.clone(),
feedback_editor,
email_address_editor,
pending_submission: false,
awaiting_submission: false,
user_submitted: false,
character_count: 0,
}
}
@ -163,37 +199,53 @@ impl FeedbackModal {
}
};
this.update(&mut cx, |feedback_editor, cx| {
feedback_editor.set_pending_submission(true, cx);
this.update(&mut cx, |this, cx| {
this.set_awaiting_submission(true, cx);
})
.log_err();
if let Err(error) =
FeedbackModal::submit_feedback(&feedback_text, email, client, specs).await
{
log::error!("{}", error);
this.update(&mut cx, |feedback_editor, cx| {
let prompt = cx.prompt(
PromptLevel::Critical,
FEEDBACK_SUBMISSION_ERROR_TEXT,
&["OK"],
);
cx.spawn(|_, _cx| async move {
prompt.await.ok();
let res =
FeedbackModal::submit_feedback(&feedback_text, email, client, specs).await;
match res {
Ok(_) => {
this.update(&mut cx, |this, cx| {
this.set_user_submitted(true, cx);
cx.emit(DismissEvent)
})
.detach();
feedback_editor.set_pending_submission(false, cx);
})
.log_err();
.ok();
}
Err(error) => {
log::error!("{}", error);
this.update(&mut cx, |this, cx| {
let prompt = cx.prompt(
PromptLevel::Critical,
FEEDBACK_SUBMISSION_ERROR_TEXT,
&["OK"],
);
cx.spawn(|_, _cx| async move {
prompt.await.ok();
})
.detach();
this.set_awaiting_submission(false, cx);
})
.log_err();
}
}
}
})
.detach();
Task::ready(Ok(()))
}
fn set_pending_submission(&mut self, pending_submission: bool, cx: &mut ViewContext<Self>) {
self.pending_submission = pending_submission;
fn set_awaiting_submission(&mut self, awaiting_submission: bool, cx: &mut ViewContext<Self>) {
self.awaiting_submission = awaiting_submission;
cx.notify();
}
fn set_user_submitted(&mut self, user_submitted: bool, cx: &mut ViewContext<Self>) {
self.user_submitted = user_submitted;
cx.notify();
}
@ -203,6 +255,14 @@ impl FeedbackModal {
zed_client: Arc<Client>,
system_specs: SystemSpecs,
) -> anyhow::Result<()> {
if DEV_MODE {
if SEND_SUCCESS_IN_DEV_MODE {
return Ok(());
} else {
return Err(anyhow!("Error submitting feedback"));
}
}
let feedback_endpoint = format!("{}/api/feedback", *ZED_SERVER_URL);
let telemetry = zed_client.telemetry();
let metrics_id = telemetry.metrics_id();
@ -233,11 +293,8 @@ impl FeedbackModal {
}
// TODO: Escape button calls dismiss
// TODO: Should do same as hitting cancel / clicking outside of modal
// Close immediately if no text in field
// Ask to close if text in the field
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
cx.emit(DismissEvent);
cx.emit(DismissEvent)
}
}
@ -251,136 +308,128 @@ impl Render for FeedbackModal {
};
let valid_character_count = FEEDBACK_CHAR_LIMIT.contains(&self.character_count);
let characters_remaining =
if valid_character_count || self.character_count > *FEEDBACK_CHAR_LIMIT.end() {
*FEEDBACK_CHAR_LIMIT.end() as i32 - self.character_count as i32
} else {
self.character_count as i32 - *FEEDBACK_CHAR_LIMIT.start() as i32
};
let allow_submission =
valid_character_count && valid_email_address && !self.pending_submission;
valid_character_count && valid_email_address && !self.awaiting_submission;
let has_feedback = self.feedback_editor.read(cx).text_option(cx).is_some();
let submit_button_text = if self.pending_submission {
"Sending..."
let submit_button_text = if self.awaiting_submission {
"Submitting..."
} else {
"Send Feedback"
"Submit"
};
let dismiss = cx.listener(|_, _, cx| {
cx.emit(DismissEvent);
});
// TODO: get the "are you sure you want to dismiss?" prompt here working
let dismiss_prompt = cx.listener(|_, _, _| {
// let answer = cx.prompt(PromptLevel::Info, "Exit feedback?", &["Yes", "No"]);
// cx.spawn(|_, _| async move {
// let answer = answer.await.ok();
// if answer == Some(0) {
// cx.emit(DismissEvent);
// }
// })
// .detach();
});
let open_community_repo =
cx.listener(|_, _, cx| cx.dispatch_action(Box::new(OpenZedCommunityRepo)));
// TODO: Nate UI pass
// Moved this here because providing it inline breaks rustfmt
let provide_an_email_address =
"Provide an email address if you want us to be able to reply.";
v_stack()
.elevation_3(cx)
.key_context("GiveFeedback")
.on_action(cx.listener(Self::cancel))
.min_w(rems(40.))
.max_w(rems(96.))
.border()
.border_color(red())
.h(rems(40.))
.p_2()
.gap_2()
.h(rems(32.))
.p_4()
.gap_4()
.child(v_stack().child(
// TODO: Add Headline component to `ui2`
div().text_xl().child("Share Feedback"),
))
.child(
v_stack().child(
div()
.size_full()
.child(Label::new("Give Feedback").color(Color::Default))
.child(Label::new("This editor supports markdown").color(Color::Muted)),
),
Label::new(if self.character_count < *FEEDBACK_CHAR_LIMIT.start() {
format!(
"Feedback must be at least {} characters.",
FEEDBACK_CHAR_LIMIT.start()
)
} else {
format!(
"Characters: {}",
*FEEDBACK_CHAR_LIMIT.end() - self.character_count
)
})
.color(if valid_character_count {
Color::Success
} else {
Color::Error
}),
)
.child(
div()
.flex_1()
.bg(cx.theme().colors().editor_background)
.p_2()
.border()
.rounded_md()
.border_color(cx.theme().colors().border)
.child(self.feedback_editor.clone()),
)
.child(
div().child(
Label::new(format!(
"Characters: {}",
characters_remaining
))
.color(
if valid_character_count {
Color::Success
} else {
Color::Error
}
)
),
)
.child(
div()
.bg(cx.theme().colors().editor_background)
.border()
.border_color(cx.theme().colors().border)
.child(self.email_address_editor.clone())
)
.child(
h_stack()
.justify_between()
.gap_1()
.child(Button::new("community_repo", "Community Repo")
.style(ButtonStyle::Filled)
.color(Color::Muted)
.on_click(open_community_repo)
.child(
h_stack()
.bg(cx.theme().colors().editor_background)
.p_2()
.border()
.rounded_md()
.border_color(cx.theme().colors().border)
.child(self.email_address_editor.clone()),
)
.child(h_stack().justify_between().gap_1()
.child(
Button::new("cancel_feedback", "Cancel")
.style(ButtonStyle::Subtle)
.color(Color::Muted)
// TODO: replicate this logic when clicking outside the modal
// TODO: Will require somehow overriding the modal dismal default behavior
.map(|this| {
if has_feedback {
this.on_click(dismiss_prompt)
} else {
this.on_click(dismiss)
}
})
)
.child(
Button::new("send_feedback", submit_button_text)
.color(Color::Accent)
.style(ButtonStyle::Filled)
// TODO: Ensure that while submitting, "Sending..." is shown and disable the button
// TODO: If submit errors: show popup with error, don't close modal, set text back to "Send Feedback", and re-enable button
// TODO: If submit is successful, close the modal
.on_click(cx.listener(|this, _, cx| {
let _ = this.submit(cx);
}))
.tooltip(|cx| {
Tooltip::with_meta(
"Submit feedback to the Zed team.",
None,
"Provide an email address if you want us to be able to reply.",
cx,
.child(
h_stack()
.justify_between()
.gap_1()
.child(
Button::new("community_repo", "Community Repo")
.style(ButtonStyle::Transparent)
.icon(Icon::ExternalLink)
.icon_position(IconPosition::End)
.icon_size(IconSize::Small)
.on_click(open_community_repo),
)
.child(
h_stack()
.gap_1()
.child(
Button::new("cancel_feedback", "Cancel")
.style(ButtonStyle::Subtle)
.color(Color::Muted)
.on_click(cx.listener(move |_, _, cx| {
cx.spawn(|this, mut cx| async move {
this.update(&mut cx, |_, cx| {
cx.emit(DismissEvent)
})
.ok();
})
.detach();
})),
)
})
.when(!allow_submission, |this| this.disabled(true))
),
)
.child(
Button::new("send_feedback", submit_button_text)
.color(Color::Accent)
.style(ButtonStyle::Filled)
// TODO: Ensure that while submitting, "Sending..." is shown and disable the button
// TODO: If submit errors: show popup with error, don't close modal, set text back to "Submit", and re-enable button
.on_click(cx.listener(|this, _, cx| {
this.submit(cx).detach();
}))
.tooltip(move |cx| {
Tooltip::with_meta(
"Submit feedback to the Zed team.",
None,
provide_an_email_address,
cx,
)
})
.when(!allow_submission, |this| this.disabled(true)),
),
),
),
)
}
}
// TODO: Maybe store email address whenever the modal is closed, versus just on submit, so users can remove it if they want without submitting
// TODO: Testing of various button states, dismissal prompts, etc.

View file

@ -17,9 +17,11 @@ use std::{
use text::Point;
use ui::{prelude::*, HighlightedLabel, ListItem};
use util::{paths::PathLikeWithPosition, post_inc, ResultExt};
use workspace::Workspace;
use workspace::{ModalView, Workspace};
actions!(Toggle);
actions!(file_finder, [Toggle]);
impl ModalView for FileFinder {}
pub struct FileFinder {
picker: View<Picker<FileFinderDelegate>>,

View file

@ -8,8 +8,9 @@ use text::{Bias, Point};
use theme::ActiveTheme;
use ui::{h_stack, prelude::*, v_stack, Label};
use util::paths::FILE_ROW_COLUMN_DELIMITER;
use workspace::ModalView;
actions!(Toggle);
actions!(go_to_line, [Toggle]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(GoToLine::register).detach();
@ -23,6 +24,8 @@ pub struct GoToLine {
_subscriptions: Vec<Subscription>,
}
impl ModalView for GoToLine {}
impl FocusableView for GoToLine {
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
self.line_editor.focus_handle(cx)

View file

@ -22,7 +22,7 @@ Actions are frequently unit structs, for which we have a macro. The above could
```rust
mod menu {
actions!(MoveUp, MoveDown);
actions!(gpui, [MoveUp, MoveDown]);
}
```

View file

@ -3,34 +3,33 @@ use anyhow::{anyhow, Context, Result};
use collections::HashMap;
pub use no_action::NoAction;
use serde_json::json;
use std::{
any::{Any, TypeId},
ops::Deref,
};
use std::any::{Any, TypeId};
/// Actions are used to implement keyboard-driven UI.
/// When you declare an action, you can bind keys to the action in the keymap and
/// listeners for that action in the element tree.
///
/// To declare a list of simple actions, you can use the actions! macro, which defines a simple unit struct
/// action for each listed action name.
/// action for each listed action name in the given namespace.
/// ```rust
/// actions!(MoveUp, MoveDown, MoveLeft, MoveRight, Newline);
/// actions!(editor, [MoveUp, MoveDown, MoveLeft, MoveRight, Newline]);
/// ```
/// More complex data types can also be actions. If you annotate your type with the action derive macro
/// it will be implemented and registered automatically.
/// More complex data types can also be actions, providing they implement Clone, PartialEq,
/// and serde_derive::Deserialize.
/// Use `impl_actions!` to automatically implement the action in the given namespace.
/// ```
/// #[derive(Clone, PartialEq, serde_derive::Deserialize, Action)]
/// #[derive(Clone, PartialEq, serde_derive::Deserialize)]
/// pub struct SelectNext {
/// pub replace_newest: bool,
/// }
/// impl_actions!(editor, [SelectNext]);
/// ```
///
/// If you want to control the behavior of the action trait manually, you can use the lower-level `#[register_action]`
/// macro, which only generates the code needed to register your action before `main`.
///
/// ```
/// #[gpui::register_action]
/// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::fmt::Debug)]
/// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone)]
/// pub struct Paste {
/// pub content: SharedString,
/// }
@ -38,6 +37,7 @@ use std::{
/// impl gpui::Action for Paste {
/// ///...
/// }
/// register_action!(Paste);
/// ```
pub trait Action: 'static {
fn boxed_clone(&self) -> Box<dyn Action>;
@ -56,7 +56,7 @@ pub trait Action: 'static {
impl std::fmt::Debug for dyn Action {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("dyn Action")
.field("type_name", &self.name())
.field("name", &self.name())
.finish()
}
}
@ -115,7 +115,7 @@ impl ActionRegistry {
for builder in __GPUI_ACTIONS {
let action = builder();
//todo(remove)
let name: SharedString = remove_the_2(action.name).into();
let name: SharedString = action.name.into();
self.builders_by_name.insert(name.clone(), action.build);
self.names_by_type_id.insert(action.type_id, name.clone());
self.all_names.push(name);
@ -139,11 +139,9 @@ impl ActionRegistry {
name: &str,
params: Option<serde_json::Value>,
) -> Result<Box<dyn Action>> {
//todo(remove)
let name = remove_the_2(name);
let build_action = self
.builders_by_name
.get(name.deref())
.get(name)
.ok_or_else(|| anyhow!("no action type registered for {}", name))?;
(build_action)(params.unwrap_or_else(|| json!({})))
.with_context(|| format!("Attempting to build action {}", name))
@ -155,36 +153,88 @@ impl ActionRegistry {
}
/// Defines unit structs that can be used as actions.
/// To use more complex data types as actions, annotate your type with the #[action] macro.
/// To use more complex data types as actions, use `impl_actions!`
#[macro_export]
macro_rules! actions {
() => {};
($namespace:path, [ $($name:ident),* $(,)? ]) => {
$(
#[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, gpui::serde_derive::Deserialize)]
#[serde(crate = "gpui::serde")]
pub struct $name;
( $name:ident ) => {
#[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, gpui::serde_derive::Deserialize, gpui::Action)]
#[serde(crate = "gpui::serde")]
pub struct $name;
};
gpui::__impl_action!($namespace, $name,
fn build(_: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
Ok(Box::new(Self))
}
);
( $name:ident, $($rest:tt)* ) => {
actions!($name);
actions!($($rest)*);
gpui::register_action!($name);
)*
};
}
//todo!(remove)
pub fn remove_the_2(action_name: &str) -> String {
let mut separator_matches = action_name.rmatch_indices("::");
separator_matches.next().unwrap();
let name_start_ix = separator_matches.next().map_or(0, |(ix, _)| ix + 2);
// todo!() remove the 2 replacement when migration is done
action_name[name_start_ix..]
.replace("2::", "::")
.to_string()
/// Implements the Action trait for any struct that implements Clone, Default, PartialEq, and serde_deserialize::Deserialize
#[macro_export]
macro_rules! impl_actions {
($namespace:path, [ $($name:ident),* $(,)? ]) => {
$(
gpui::__impl_action!($namespace, $name,
fn build(value: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
Ok(std::boxed::Box::new(gpui::serde_json::from_value::<Self>(value)?))
}
);
)*
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __impl_action {
($namespace:path, $name:ident, $build:item) => {
impl gpui::Action for $name {
fn name(&self) -> &'static str
{
concat!(
stringify!($namespace),
"::",
stringify!($name),
)
}
// todo!() why is this needed in addition to name?
fn debug_name() -> &'static str
where
Self: ::std::marker::Sized
{
concat!(
stringify!($namespace),
"::",
stringify!($name),
)
}
$build
fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
action
.as_any()
.downcast_ref::<Self>()
.map_or(false, |a| self == a)
}
fn boxed_clone(&self) -> std::boxed::Box<dyn gpui::Action> {
::std::boxed::Box::new(self.clone())
}
fn as_any(&self) -> &dyn ::std::any::Any {
self
}
}
};
}
mod no_action {
use crate as gpui;
actions!(NoAction);
actions!(zed, [NoAction]);
}

View file

@ -13,6 +13,7 @@ use smallvec::SmallVec;
use smol::future::FutureExt;
#[cfg(any(test, feature = "test-support"))]
pub use test_context::*;
use time::UtcOffset;
use crate::{
current_platform, image_cache::ImageCache, init_app_menus, Action, ActionRegistry, Any,
@ -536,6 +537,10 @@ impl AppContext {
self.platform.restart()
}
pub fn local_timezone(&self) -> UtcOffset {
self.platform.local_timezone()
}
pub(crate) fn push_effect(&mut self, effect: Effect) {
match &effect {
Effect::Notify { emitter } => {

View file

@ -0,0 +1,496 @@
use crate::{
px, AnyElement, AvailableSpace, BorrowAppContext, DispatchPhase, Element, IntoElement, Pixels,
Point, ScrollWheelEvent, Size, Style, StyleRefinement, Styled, WindowContext,
};
use collections::VecDeque;
use refineable::Refineable as _;
use std::{cell::RefCell, ops::Range, rc::Rc};
use sum_tree::{Bias, SumTree};
pub fn list(state: ListState) -> List {
List {
state,
style: StyleRefinement::default(),
}
}
pub struct List {
state: ListState,
style: StyleRefinement,
}
#[derive(Clone)]
pub struct ListState(Rc<RefCell<StateInner>>);
struct StateInner {
last_layout_width: Option<Pixels>,
render_item: Box<dyn FnMut(usize, &mut WindowContext) -> AnyElement>,
items: SumTree<ListItem>,
logical_scroll_top: Option<ListOffset>,
alignment: ListAlignment,
overdraw: Pixels,
#[allow(clippy::type_complexity)]
scroll_handler: Option<Box<dyn FnMut(&ListScrollEvent, &mut WindowContext)>>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ListAlignment {
Top,
Bottom,
}
pub struct ListScrollEvent {
pub visible_range: Range<usize>,
pub count: usize,
}
#[derive(Clone)]
enum ListItem {
Unrendered,
Rendered { height: Pixels },
}
#[derive(Clone, Debug, Default, PartialEq)]
struct ListItemSummary {
count: usize,
rendered_count: usize,
unrendered_count: usize,
height: Pixels,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
struct Count(usize);
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
struct RenderedCount(usize);
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
struct UnrenderedCount(usize);
#[derive(Clone, Debug, Default)]
struct Height(Pixels);
impl ListState {
pub fn new<F>(
element_count: usize,
orientation: ListAlignment,
overdraw: Pixels,
render_item: F,
) -> Self
where
F: 'static + FnMut(usize, &mut WindowContext) -> AnyElement,
{
let mut items = SumTree::new();
items.extend((0..element_count).map(|_| ListItem::Unrendered), &());
Self(Rc::new(RefCell::new(StateInner {
last_layout_width: None,
render_item: Box::new(render_item),
items,
logical_scroll_top: None,
alignment: orientation,
overdraw,
scroll_handler: None,
})))
}
pub fn reset(&self, element_count: usize) {
let state = &mut *self.0.borrow_mut();
state.logical_scroll_top = None;
state.items = SumTree::new();
state
.items
.extend((0..element_count).map(|_| ListItem::Unrendered), &());
}
pub fn item_count(&self) -> usize {
self.0.borrow().items.summary().count
}
pub fn splice(&self, old_range: Range<usize>, count: usize) {
let state = &mut *self.0.borrow_mut();
if let Some(ListOffset {
item_ix,
offset_in_item,
}) = state.logical_scroll_top.as_mut()
{
if old_range.contains(item_ix) {
*item_ix = old_range.start;
*offset_in_item = px(0.);
} else if old_range.end <= *item_ix {
*item_ix = *item_ix - (old_range.end - old_range.start) + count;
}
}
let mut old_heights = state.items.cursor::<Count>();
let mut new_heights = old_heights.slice(&Count(old_range.start), Bias::Right, &());
old_heights.seek_forward(&Count(old_range.end), Bias::Right, &());
new_heights.extend((0..count).map(|_| ListItem::Unrendered), &());
new_heights.append(old_heights.suffix(&()), &());
drop(old_heights);
state.items = new_heights;
}
pub fn set_scroll_handler(
&self,
handler: impl FnMut(&ListScrollEvent, &mut WindowContext) + 'static,
) {
self.0.borrow_mut().scroll_handler = Some(Box::new(handler))
}
pub fn logical_scroll_top(&self) -> ListOffset {
self.0.borrow().logical_scroll_top()
}
pub fn scroll_to(&self, mut scroll_top: ListOffset) {
let state = &mut *self.0.borrow_mut();
let item_count = state.items.summary().count;
if scroll_top.item_ix >= item_count {
scroll_top.item_ix = item_count;
scroll_top.offset_in_item = px(0.);
}
state.logical_scroll_top = Some(scroll_top);
}
}
impl StateInner {
fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> {
let mut cursor = self.items.cursor::<ListItemSummary>();
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
let start_y = cursor.start().height + scroll_top.offset_in_item;
cursor.seek_forward(&Height(start_y + height), Bias::Left, &());
scroll_top.item_ix..cursor.start().count + 1
}
fn scroll(
&mut self,
scroll_top: &ListOffset,
height: Pixels,
delta: Point<Pixels>,
cx: &mut WindowContext,
) {
let scroll_max = (self.items.summary().height - height).max(px(0.));
let new_scroll_top = (self.scroll_top(scroll_top) - delta.y)
.max(px(0.))
.min(scroll_max);
if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max {
self.logical_scroll_top = None;
} else {
let mut cursor = self.items.cursor::<ListItemSummary>();
cursor.seek(&Height(new_scroll_top), Bias::Right, &());
let item_ix = cursor.start().count;
let offset_in_item = new_scroll_top - cursor.start().height;
self.logical_scroll_top = Some(ListOffset {
item_ix,
offset_in_item,
});
}
if self.scroll_handler.is_some() {
let visible_range = self.visible_range(height, scroll_top);
self.scroll_handler.as_mut().unwrap()(
&ListScrollEvent {
visible_range,
count: self.items.summary().count,
},
cx,
);
}
cx.notify();
}
fn logical_scroll_top(&self) -> ListOffset {
self.logical_scroll_top
.unwrap_or_else(|| match self.alignment {
ListAlignment::Top => ListOffset {
item_ix: 0,
offset_in_item: px(0.),
},
ListAlignment::Bottom => ListOffset {
item_ix: self.items.summary().count,
offset_in_item: px(0.),
},
})
}
fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels {
let mut cursor = self.items.cursor::<ListItemSummary>();
cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right, &());
cursor.start().height + logical_scroll_top.offset_in_item
}
}
impl std::fmt::Debug for ListItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Unrendered => write!(f, "Unrendered"),
Self::Rendered { height, .. } => {
f.debug_struct("Rendered").field("height", height).finish()
}
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ListOffset {
pub item_ix: usize,
pub offset_in_item: Pixels,
}
impl Element for List {
type State = ();
fn layout(
&mut self,
_state: Option<Self::State>,
cx: &mut crate::WindowContext,
) -> (crate::LayoutId, Self::State) {
let mut style = Style::default();
style.refine(&self.style);
let layout_id = cx.with_text_style(style.text_style().cloned(), |cx| {
cx.request_layout(&style, None)
});
(layout_id, ())
}
fn paint(
self,
bounds: crate::Bounds<crate::Pixels>,
_state: &mut Self::State,
cx: &mut crate::WindowContext,
) {
let state = &mut *self.state.0.borrow_mut();
// If the width of the list has changed, invalidate all cached item heights
if state.last_layout_width != Some(bounds.size.width) {
state.items = SumTree::from_iter(
(0..state.items.summary().count).map(|_| ListItem::Unrendered),
&(),
)
}
let old_items = state.items.clone();
let mut measured_items = VecDeque::new();
let mut item_elements = VecDeque::new();
let mut rendered_height = px(0.);
let mut scroll_top = state.logical_scroll_top();
let available_item_space = Size {
width: AvailableSpace::Definite(bounds.size.width),
height: AvailableSpace::MinContent,
};
// Render items after the scroll top, including those in the trailing overdraw
let mut cursor = old_items.cursor::<Count>();
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
for (ix, item) in cursor.by_ref().enumerate() {
let visible_height = rendered_height - scroll_top.offset_in_item;
if visible_height >= bounds.size.height + state.overdraw {
break;
}
// Use the previously cached height if available
let mut height = if let ListItem::Rendered { height } = item {
Some(*height)
} else {
None
};
// If we're within the visible area or the height wasn't cached, render and measure the item's element
if visible_height < bounds.size.height || height.is_none() {
let mut element = (state.render_item)(scroll_top.item_ix + ix, cx);
let element_size = element.measure(available_item_space, cx);
height = Some(element_size.height);
if visible_height < bounds.size.height {
item_elements.push_back(element);
}
}
let height = height.unwrap();
rendered_height += height;
measured_items.push_back(ListItem::Rendered { height });
}
// Prepare to start walking upward from the item at the scroll top.
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
// If the rendered items do not fill the visible region, then adjust
// the scroll top upward.
if rendered_height - scroll_top.offset_in_item < bounds.size.height {
while rendered_height < bounds.size.height {
cursor.prev(&());
if cursor.item().is_some() {
let mut element = (state.render_item)(cursor.start().0, cx);
let element_size = element.measure(available_item_space, cx);
rendered_height += element_size.height;
measured_items.push_front(ListItem::Rendered {
height: element_size.height,
});
item_elements.push_front(element)
} else {
break;
}
}
scroll_top = ListOffset {
item_ix: cursor.start().0,
offset_in_item: rendered_height - bounds.size.height,
};
match state.alignment {
ListAlignment::Top => {
scroll_top.offset_in_item = scroll_top.offset_in_item.max(px(0.));
state.logical_scroll_top = Some(scroll_top);
}
ListAlignment::Bottom => {
scroll_top = ListOffset {
item_ix: cursor.start().0,
offset_in_item: rendered_height - bounds.size.height,
};
state.logical_scroll_top = None;
}
};
}
// Measure items in the leading overdraw
let mut leading_overdraw = scroll_top.offset_in_item;
while leading_overdraw < state.overdraw {
cursor.prev(&());
if let Some(item) = cursor.item() {
let height = if let ListItem::Rendered { height } = item {
*height
} else {
let mut element = (state.render_item)(cursor.start().0, cx);
element.measure(available_item_space, cx).height
};
leading_overdraw += height;
measured_items.push_front(ListItem::Rendered { height });
} else {
break;
}
}
let measured_range = cursor.start().0..(cursor.start().0 + measured_items.len());
let mut cursor = old_items.cursor::<Count>();
let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right, &());
new_items.extend(measured_items, &());
cursor.seek(&Count(measured_range.end), Bias::Right, &());
new_items.append(cursor.suffix(&()), &());
// Paint the visible items
let mut item_origin = bounds.origin;
item_origin.y -= scroll_top.offset_in_item;
for mut item_element in item_elements {
let item_height = item_element.measure(available_item_space, cx).height;
item_element.draw(item_origin, available_item_space, cx);
item_origin.y += item_height;
}
state.items = new_items;
state.last_layout_width = Some(bounds.size.width);
let list_state = self.state.clone();
let height = bounds.size.height;
cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| {
if phase == DispatchPhase::Bubble {
list_state.0.borrow_mut().scroll(
&scroll_top,
height,
event.delta.pixel_delta(px(20.)),
cx,
)
}
});
}
}
impl IntoElement for List {
type Element = Self;
fn element_id(&self) -> Option<crate::ElementId> {
None
}
fn into_element(self) -> Self::Element {
self
}
}
impl Styled for List {
fn style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
impl sum_tree::Item for ListItem {
type Summary = ListItemSummary;
fn summary(&self) -> Self::Summary {
match self {
ListItem::Unrendered => ListItemSummary {
count: 1,
rendered_count: 0,
unrendered_count: 1,
height: px(0.),
},
ListItem::Rendered { height } => ListItemSummary {
count: 1,
rendered_count: 1,
unrendered_count: 0,
height: *height,
},
}
}
}
impl sum_tree::Summary for ListItemSummary {
type Context = ();
fn add_summary(&mut self, summary: &Self, _: &()) {
self.count += summary.count;
self.rendered_count += summary.rendered_count;
self.unrendered_count += summary.unrendered_count;
self.height += summary.height;
}
}
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count {
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.count;
}
}
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for RenderedCount {
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.rendered_count;
}
}
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for UnrenderedCount {
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.unrendered_count;
}
}
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height {
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
self.0 += summary.height;
}
}
impl<'a> sum_tree::SeekTarget<'a, ListItemSummary, ListItemSummary> for Count {
fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering {
self.0.partial_cmp(&other.count).unwrap()
}
}
impl<'a> sum_tree::SeekTarget<'a, ListItemSummary, ListItemSummary> for Height {
fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering {
self.0.partial_cmp(&other.height).unwrap()
}
}

View file

@ -1,6 +1,7 @@
mod canvas;
mod div;
mod img;
mod list;
mod overlay;
mod svg;
mod text;
@ -9,6 +10,7 @@ mod uniform_list;
pub use canvas::*;
pub use div::*;
pub use img::*;
pub use list::*;
pub use overlay::*;
pub use svg::*;
pub use text::*;

View file

@ -131,7 +131,7 @@ impl Element for UniformList {
}
});
let height = match available_space.height {
AvailableSpace::Definite(x) => desired_height.min(x),
AvailableSpace::Definite(height) => desired_height.min(height),
AvailableSpace::MinContent | AvailableSpace::MaxContent => {
desired_height
}

View file

@ -1,6 +1,7 @@
#[macro_use]
mod action;
mod app;
mod assets;
mod color;
mod element;
@ -15,6 +16,7 @@ mod keymap;
mod platform;
pub mod prelude;
mod scene;
mod shared_string;
mod style;
mod styled;
mod subscription;
@ -57,6 +59,7 @@ pub use scene::*;
pub use serde;
pub use serde_derive;
pub use serde_json;
pub use shared_string::*;
pub use smallvec;
pub use smol::Timer;
pub use style::*;
@ -71,10 +74,9 @@ pub use util::arc_cow::ArcCow;
pub use view::*;
pub use window::*;
use derive_more::{Deref, DerefMut};
use std::{
any::{Any, TypeId},
borrow::{Borrow, BorrowMut},
borrow::BorrowMut,
};
use taffy::TaffyLayoutEngine;
@ -209,42 +211,3 @@ impl<T> Flatten<T> for Result<T> {
self
}
}
#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
pub struct SharedString(ArcCow<'static, str>);
impl Default for SharedString {
fn default() -> Self {
Self(ArcCow::Owned("".into()))
}
}
impl AsRef<str> for SharedString {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Borrow<str> for SharedString {
fn borrow(&self) -> &str {
self.as_ref()
}
}
impl std::fmt::Debug for SharedString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::fmt::Display for SharedString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.as_ref())
}
}
impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
fn from(value: T) -> Self {
Self(value.into())
}
}

View file

@ -302,7 +302,7 @@ mod test {
focus_handle: FocusHandle,
}
actions!(TestAction);
actions!(test, [TestAction]);
impl Render for TestView {
type Element = Stateful<Div>;

View file

@ -149,13 +149,19 @@ impl DispatchTree {
}
pub fn available_actions(&self, target: DispatchNodeId) -> Vec<Box<dyn Action>> {
let mut actions = Vec::new();
let mut actions = Vec::<Box<dyn Action>>::new();
for node_id in self.dispatch_path(target) {
let node = &self.nodes[node_id.0];
for DispatchActionListener { action_type, .. } in &node.action_listeners {
// Intentionally silence these errors without logging.
// If an action cannot be built by default, it's not available.
actions.extend(self.action_registry.build_action_type(action_type).ok());
if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id())
{
// Intentionally silence these errors without logging.
// If an action cannot be built by default, it's not available.
let action = self.action_registry.build_action_type(action_type).ok();
if let Some(action) = action {
actions.insert(ix, action);
}
}
}
}
actions

View file

@ -293,11 +293,13 @@ mod tests {
#[test]
fn test_actions_definition() {
{
actions!(A, B, C, D, E, F, G);
actions!(test, [A, B, C, D, E, F, G]);
}
{
actions!(
test,
[
A,
B,
C,
@ -305,6 +307,7 @@ mod tests {
E,
F,
G, // Don't wrap, test the trailing comma
]
);
}
}

View file

@ -0,0 +1,101 @@
use derive_more::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use std::{borrow::Borrow, sync::Arc};
use util::arc_cow::ArcCow;
#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
pub struct SharedString(ArcCow<'static, str>);
impl Default for SharedString {
fn default() -> Self {
Self(ArcCow::Owned("".into()))
}
}
impl AsRef<str> for SharedString {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Borrow<str> for SharedString {
fn borrow(&self) -> &str {
self.as_ref()
}
}
impl std::fmt::Debug for SharedString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::fmt::Display for SharedString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0.as_ref())
}
}
impl PartialEq<String> for SharedString {
fn eq(&self, other: &String) -> bool {
self.as_ref() == other
}
}
impl PartialEq<SharedString> for String {
fn eq(&self, other: &SharedString) -> bool {
self == other.as_ref()
}
}
impl PartialEq<str> for SharedString {
fn eq(&self, other: &str) -> bool {
self.as_ref() == other
}
}
impl<'a> PartialEq<&'a str> for SharedString {
fn eq(&self, other: &&'a str) -> bool {
self.as_ref() == *other
}
}
impl Into<Arc<str>> for SharedString {
fn into(self) -> Arc<str> {
match self.0 {
ArcCow::Borrowed(borrowed) => Arc::from(borrowed),
ArcCow::Owned(owned) => owned.clone(),
}
}
}
impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
fn from(value: T) -> Self {
Self(value.into())
}
}
impl Into<String> for SharedString {
fn into(self) -> String {
self.0.to_string()
}
}
impl Serialize for SharedString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_ref())
}
}
impl<'de> Deserialize<'de> for SharedString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(SharedString::from(s))
}
}

View file

@ -245,6 +245,13 @@ pub trait Styled: Sized {
self
}
/// Sets the flex direction of the element to `column-reverse`.
/// [Docs](https://tailwindcss.com/docs/flex-direction#column-reverse)
fn flex_col_reverse(mut self) -> Self {
self.style().flex_direction = Some(FlexDirection::ColumnReverse);
self
}
/// Sets the flex direction of the element to `row`.
/// [Docs](https://tailwindcss.com/docs/flex-direction#row)
fn flex_row(mut self) -> Self {
@ -252,6 +259,13 @@ pub trait Styled: Sized {
self
}
/// Sets the flex direction of the element to `row-reverse`.
/// [Docs](https://tailwindcss.com/docs/flex-direction#row-reverse)
fn flex_row_reverse(mut self) -> Self {
self.style().flex_direction = Some(FlexDirection::RowReverse);
self
}
/// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
/// [Docs](https://tailwindcss.com/docs/flex#flex-1)
fn flex_1(mut self) -> Self {

View file

@ -1,16 +1,23 @@
use gpui2::{actions, impl_actions};
use gpui2_macros::register_action;
use serde_derive::Deserialize;
#[test]
fn test_derive() {
fn test_action_macros() {
use gpui2 as gpui;
#[derive(PartialEq, Clone, Deserialize, gpui2_macros::Action)]
actions!(test, [TestAction]);
#[derive(PartialEq, Clone, Deserialize)]
struct AnotherTestAction;
#[gpui2_macros::register_action]
impl_actions!(test, [AnotherTestAction]);
#[derive(PartialEq, Clone, gpui::serde_derive::Deserialize)]
struct RegisterableAction {}
register_action!(RegisterableAction);
impl gpui::Action for RegisterableAction {
fn boxed_clone(&self) -> Box<dyn gpui::Action> {
todo!()

View file

@ -1,97 +0,0 @@
// Input:
//
// #[action]
// struct Foo {
// bar: String,
// }
// Output:
//
// #[gpui::register_action]
// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
// struct Foo {
// bar: String,
// }
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Error};
use crate::register_action::register_action;
pub fn action(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
if input.generics.lt_token.is_some() {
return Error::new(name.span(), "Actions must be a concrete type")
.into_compile_error()
.into();
}
let is_unit_struct = match input.data {
syn::Data::Struct(struct_data) => struct_data.fields.is_empty(),
syn::Data::Enum(_) => false,
syn::Data::Union(_) => false,
};
let build_impl = if is_unit_struct {
quote! {
let _ = value;
Ok(std::boxed::Box::new(Self {}))
}
} else {
quote! {
Ok(std::boxed::Box::new(gpui::serde_json::from_value::<Self>(value)?))
}
};
let register_action = register_action(&name);
let output = quote! {
const _: fn() = || {
fn assert_impl<T: ?Sized + for<'a> gpui::serde::Deserialize<'a> + ::std::cmp::PartialEq + ::std::clone::Clone>() {}
assert_impl::<#name>();
};
impl gpui::Action for #name {
fn name(&self) -> &'static str
{
::std::any::type_name::<#name>()
}
fn debug_name() -> &'static str
where
Self: ::std::marker::Sized
{
::std::any::type_name::<#name>()
}
fn build(value: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>>
where
Self: ::std::marker::Sized {
#build_impl
}
fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
action
.as_any()
.downcast_ref::<Self>()
.map_or(false, |a| self == a)
}
fn boxed_clone(&self) -> std::boxed::Box<dyn gpui::Action> {
::std::boxed::Box::new(self.clone())
}
fn as_any(&self) -> &dyn ::std::any::Any {
self
}
}
#register_action
};
TokenStream::from(output)
}

View file

@ -1,4 +1,3 @@
mod action;
mod derive_into_element;
mod register_action;
mod style_helpers;
@ -6,14 +5,9 @@ mod test;
use proc_macro::TokenStream;
#[proc_macro_derive(Action)]
pub fn action(input: TokenStream) -> TokenStream {
action::action(input)
}
#[proc_macro_attribute]
pub fn register_action(attr: TokenStream, item: TokenStream) -> TokenStream {
register_action::register_action_macro(attr, item)
#[proc_macro]
pub fn register_action(ident: TokenStream) -> TokenStream {
register_action::register_action_macro(ident)
}
#[proc_macro_derive(IntoElement)]

View file

@ -14,47 +14,13 @@
use proc_macro::TokenStream;
use proc_macro2::Ident;
use quote::{format_ident, quote};
use syn::{parse_macro_input, DeriveInput, Error};
use syn::parse_macro_input;
pub fn register_action_macro(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
let registration = register_action(&input.ident);
let has_action_derive = input
.attrs
.iter()
.find(|attr| {
(|| {
let meta = attr.parse_meta().ok()?;
meta.path().is_ident("derive").then(|| match meta {
syn::Meta::Path(_) => None,
syn::Meta::NameValue(_) => None,
syn::Meta::List(list) => list
.nested
.iter()
.find(|list| match list {
syn::NestedMeta::Meta(meta) => meta.path().is_ident("Action"),
syn::NestedMeta::Lit(_) => false,
})
.map(|_| true),
})?
})()
.unwrap_or(false)
})
.is_some();
if has_action_derive {
return Error::new(
input.ident.span(),
"The Action derive macro has already registered this action",
)
.into_compile_error()
.into();
}
pub fn register_action_macro(ident: TokenStream) -> TokenStream {
let name = parse_macro_input!(ident as Ident);
let registration = register_action(&name);
TokenStream::from(quote! {
#input
#registration
})
}
@ -78,7 +44,7 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
#[doc(hidden)]
fn #action_builder_fn_name() -> gpui::ActionData {
gpui::ActionData {
name: ::std::any::type_name::<#type_name>(),
name: <#type_name as gpui::Action>::debug_name(),
type_id: ::std::any::TypeId::of::<#type_name>(),
build: <#type_name as gpui::Action>::build,
}

View file

@ -3,7 +3,7 @@ use gpui::{actions, AsyncAppContext};
use std::path::Path;
use util::ResultExt;
actions!(Install);
actions!(cli, [Install]);
pub async fn install_cli(cx: &AsyncAppContext) -> Result<()> {
let cli_path = cx.update(|cx| cx.path_for_auxiliary_executable("cli"))??;

View file

@ -14,9 +14,9 @@ use project::Project;
use std::sync::Arc;
use ui::{prelude::*, HighlightedLabel, ListItem};
use util::ResultExt;
use workspace::Workspace;
use workspace::{ModalView, Workspace};
actions!(Toggle);
actions!(language_selector, [Toggle]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(LanguageSelector::register).detach();
@ -81,6 +81,7 @@ impl FocusableView for LanguageSelector {
}
impl EventEmitter<DismissEvent> for LanguageSelector {}
impl ModalView for LanguageSelector {}
pub struct LanguageSelectorDelegate {
language_selector: WeakView<LanguageSelector>,

View file

@ -1,17 +1,15 @@
use std::{sync::Arc, time::Duration};
use futures::StreamExt;
use gpui::{Action, KeyBinding};
use gpui::{actions, KeyBinding};
use live_kit_client2::{
LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room,
};
use live_kit_server::token::{self, VideoGrant};
use log::LevelFilter;
use serde_derive::Deserialize;
use simplelog::SimpleLogger;
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Action)]
struct Quit;
actions!(live_kit_client, [Quit]);
fn main() {
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");

View file

@ -10,12 +10,15 @@ use gpui::actions;
pub fn init() {}
actions!(
Cancel,
Confirm,
SecondaryConfirm,
SelectPrev,
SelectNext,
SelectFirst,
SelectLast,
ShowContextMenu
menu,
[
Cancel,
Confirm,
SecondaryConfirm,
SelectPrev,
SelectNext,
SelectFirst,
SelectLast,
ShowContextMenu
]
);

View file

@ -20,9 +20,9 @@ use std::{
use theme::{color_alpha, ActiveTheme, ThemeSettings};
use ui::{prelude::*, ListItem};
use util::ResultExt;
use workspace::Workspace;
use workspace::{ModalView, Workspace};
actions!(Toggle);
actions!(outline, [Toggle]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(OutlineView::register).detach();
@ -57,6 +57,7 @@ impl FocusableView for OutlineView {
}
impl EventEmitter<DismissEvent> for OutlineView {}
impl ModalView for OutlineView {}
impl Render for OutlineView {
type Element = Div;

View file

@ -103,23 +103,26 @@ pub struct EntryDetails {
}
actions!(
ExpandSelectedEntry,
CollapseSelectedEntry,
CollapseAllEntries,
NewDirectory,
NewFile,
Copy,
CopyPath,
CopyRelativePath,
RevealInFinder,
OpenInTerminal,
Cut,
Paste,
Delete,
Rename,
Open,
ToggleFocus,
NewSearchInDirectory,
project_panel,
[
ExpandSelectedEntry,
CollapseSelectedEntry,
CollapseAllEntries,
NewDirectory,
NewFile,
Copy,
CopyPath,
CopyRelativePath,
RevealInFinder,
OpenInTerminal,
Cut,
Paste,
Delete,
Rename,
Open,
ToggleFocus,
NewSearchInDirectory,
]
);
pub fn init_settings(cx: &mut AppContext) {

View file

@ -1 +1 @@
gpui::actions!(OpenRecent);
gpui::actions!(projects, [OpenRecent]);

View file

@ -13,8 +13,8 @@ use std::sync::Arc;
use ui::{prelude::*, ListItem};
use util::paths::PathExt;
use workspace::{
notifications::simple_message_notification::MessageNotification, Workspace, WorkspaceLocation,
WORKSPACE_DB,
notifications::simple_message_notification::MessageNotification, ModalView, Workspace,
WorkspaceLocation, WORKSPACE_DB,
};
pub use projects::OpenRecent;
@ -27,6 +27,8 @@ pub struct RecentProjects {
picker: View<Picker<RecentProjectsDelegate>>,
}
impl ModalView for RecentProjects {}
impl RecentProjects {
fn new(delegate: RecentProjectsDelegate, cx: &mut ViewContext<Self>) -> Self {
Self {

View file

@ -1,13 +1,16 @@
use std::{ops::Range, sync::Arc};
use anyhow::bail;
use futures::FutureExt;
use gpui::{AnyElement, FontStyle, FontWeight, HighlightStyle, UnderlineStyle};
use gpui::{
AnyElement, ElementId, FontStyle, FontWeight, HighlightStyle, InteractiveText, IntoElement,
SharedString, StyledText, UnderlineStyle, WindowContext,
};
use language::{HighlightId, Language, LanguageRegistry};
use std::{ops::Range, sync::Arc};
use theme::ActiveTheme;
use util::RangeExt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Highlight {
Code,
Id(HighlightId),
Highlight(HighlightStyle),
Mention,
@ -28,24 +31,10 @@ impl From<HighlightId> for Highlight {
#[derive(Debug, Clone)]
pub struct RichText {
pub text: String,
pub text: SharedString,
pub highlights: Vec<(Range<usize>, Highlight)>,
pub region_ranges: Vec<Range<usize>>,
pub regions: Vec<RenderedRegion>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BackgroundKind {
Code,
/// A mention background for non-self user.
Mention,
SelfMention,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RenderedRegion {
pub background_kind: Option<BackgroundKind>,
pub link_url: Option<String>,
pub link_ranges: Vec<Range<usize>>,
pub link_urls: Arc<[String]>,
}
/// Allows one to specify extra links to the rendered markdown, which can be used
@ -56,94 +45,71 @@ pub struct Mention {
}
impl RichText {
pub fn element(
&self,
// syntax: Arc<SyntaxTheme>,
// style: RichTextStyle,
// cx: &mut ViewContext<V>,
) -> AnyElement {
todo!();
pub fn element(&self, id: ElementId, cx: &mut WindowContext) -> AnyElement {
let theme = cx.theme();
let code_background = theme.colors().surface_background;
// let mut region_id = 0;
// let view_id = cx.view_id();
// let regions = self.regions.clone();
// enum Markdown {}
// Text::new(self.text.clone(), style.text.clone())
// .with_highlights(
// self.highlights
// .iter()
// .filter_map(|(range, highlight)| {
// let style = match highlight {
// Highlight::Id(id) => id.style(&syntax)?,
// Highlight::Highlight(style) => style.clone(),
// Highlight::Mention => style.mention_highlight,
// Highlight::SelfMention => style.self_mention_highlight,
// };
// Some((range.clone(), style))
// })
// .collect::<Vec<_>>(),
// )
// .with_custom_runs(self.region_ranges.clone(), move |ix, bounds, cx| {
// region_id += 1;
// let region = regions[ix].clone();
// if let Some(url) = region.link_url {
// cx.scene().push_cursor_region(CursorRegion {
// bounds,
// style: CursorStyle::PointingHand,
// });
// cx.scene().push_mouse_region(
// MouseRegion::new::<Markdown>(view_id, region_id, bounds)
// .on_click::<V, _>(MouseButton::Left, move |_, _, cx| {
// cx.platform().open_url(&url)
// }),
// );
// }
// if let Some(region_kind) = &region.background_kind {
// let background = match region_kind {
// BackgroundKind::Code => style.code_background,
// BackgroundKind::Mention => style.mention_background,
// BackgroundKind::SelfMention => style.self_mention_background,
// };
// if background.is_some() {
// cx.scene().push_quad(gpui::Quad {
// bounds,
// background,
// border: Default::default(),
// corner_radii: (2.0).into(),
// });
// }
// }
// })
// .with_soft_wrap(true)
// .into_any()
InteractiveText::new(
id,
StyledText::new(self.text.clone()).with_highlights(
&cx.text_style(),
self.highlights.iter().map(|(range, highlight)| {
(
range.clone(),
match highlight {
Highlight::Code => HighlightStyle {
background_color: Some(code_background),
..Default::default()
},
Highlight::Id(id) => HighlightStyle {
background_color: Some(code_background),
..id.style(&theme.syntax()).unwrap_or_default()
},
Highlight::Highlight(highlight) => *highlight,
Highlight::Mention => HighlightStyle {
font_weight: Some(FontWeight::BOLD),
..Default::default()
},
Highlight::SelfMention => HighlightStyle {
font_weight: Some(FontWeight::BOLD),
..Default::default()
},
},
)
}),
),
)
.on_click(self.link_ranges.clone(), {
let link_urls = self.link_urls.clone();
move |ix, cx| cx.open_url(&link_urls[ix])
})
.into_any_element()
}
pub fn add_mention(
&mut self,
range: Range<usize>,
is_current_user: bool,
mention_style: HighlightStyle,
) -> anyhow::Result<()> {
if range.end > self.text.len() {
bail!(
"Mention in range {range:?} is outside of bounds for a message of length {}",
self.text.len()
);
}
// pub fn add_mention(
// &mut self,
// range: Range<usize>,
// is_current_user: bool,
// mention_style: HighlightStyle,
// ) -> anyhow::Result<()> {
// if range.end > self.text.len() {
// bail!(
// "Mention in range {range:?} is outside of bounds for a message of length {}",
// self.text.len()
// );
// }
if is_current_user {
self.region_ranges.push(range.clone());
self.regions.push(RenderedRegion {
background_kind: Some(BackgroundKind::Mention),
link_url: None,
});
}
self.highlights
.push((range, Highlight::Highlight(mention_style)));
Ok(())
}
// if is_current_user {
// self.region_ranges.push(range.clone());
// self.regions.push(RenderedRegion {
// background_kind: Some(BackgroundKind::Mention),
// link_url: None,
// });
// }
// self.highlights
// .push((range, Highlight::Highlight(mention_style)));
// Ok(())
// }
}
pub fn render_markdown_mut(
@ -151,7 +117,10 @@ pub fn render_markdown_mut(
mut mentions: &[Mention],
language_registry: &Arc<LanguageRegistry>,
language: Option<&Arc<Language>>,
data: &mut RichText,
text: &mut String,
highlights: &mut Vec<(Range<usize>, Highlight)>,
link_ranges: &mut Vec<Range<usize>>,
link_urls: &mut Vec<String>,
) {
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
@ -163,18 +132,18 @@ pub fn render_markdown_mut(
let options = Options::all();
for (event, source_range) in Parser::new_ext(&block, options).into_offset_iter() {
let prev_len = data.text.len();
let prev_len = text.len();
match event {
Event::Text(t) => {
if let Some(language) = &current_language {
render_code(&mut data.text, &mut data.highlights, t.as_ref(), language);
render_code(text, highlights, t.as_ref(), language);
} else {
if let Some(mention) = mentions.first() {
if source_range.contains_inclusive(&mention.range) {
mentions = &mentions[1..];
let range = (prev_len + mention.range.start - source_range.start)
..(prev_len + mention.range.end - source_range.start);
data.highlights.push((
highlights.push((
range.clone(),
if mention.is_self_mention {
Highlight::SelfMention
@ -182,19 +151,10 @@ pub fn render_markdown_mut(
Highlight::Mention
},
));
data.region_ranges.push(range);
data.regions.push(RenderedRegion {
background_kind: Some(if mention.is_self_mention {
BackgroundKind::SelfMention
} else {
BackgroundKind::Mention
}),
link_url: None,
});
}
}
data.text.push_str(t.as_ref());
text.push_str(t.as_ref());
let mut style = HighlightStyle::default();
if bold_depth > 0 {
style.font_weight = Some(FontWeight::BOLD);
@ -203,11 +163,8 @@ pub fn render_markdown_mut(
style.font_style = Some(FontStyle::Italic);
}
if let Some(link_url) = link_url.clone() {
data.region_ranges.push(prev_len..data.text.len());
data.regions.push(RenderedRegion {
link_url: Some(link_url),
background_kind: None,
});
link_ranges.push(prev_len..text.len());
link_urls.push(link_url);
style.underline = Some(UnderlineStyle {
thickness: 1.0.into(),
..Default::default()
@ -216,27 +173,25 @@ pub fn render_markdown_mut(
if style != HighlightStyle::default() {
let mut new_highlight = true;
if let Some((last_range, last_style)) = data.highlights.last_mut() {
if let Some((last_range, last_style)) = highlights.last_mut() {
if last_range.end == prev_len
&& last_style == &Highlight::Highlight(style)
{
last_range.end = data.text.len();
last_range.end = text.len();
new_highlight = false;
}
}
if new_highlight {
data.highlights
.push((prev_len..data.text.len(), Highlight::Highlight(style)));
highlights.push((prev_len..text.len(), Highlight::Highlight(style)));
}
}
}
}
Event::Code(t) => {
data.text.push_str(t.as_ref());
data.region_ranges.push(prev_len..data.text.len());
text.push_str(t.as_ref());
if link_url.is_some() {
data.highlights.push((
prev_len..data.text.len(),
highlights.push((
prev_len..text.len(),
Highlight::Highlight(HighlightStyle {
underline: Some(UnderlineStyle {
thickness: 1.0.into(),
@ -246,19 +201,19 @@ pub fn render_markdown_mut(
}),
));
}
data.regions.push(RenderedRegion {
background_kind: Some(BackgroundKind::Code),
link_url: link_url.clone(),
});
if let Some(link_url) = link_url.clone() {
link_ranges.push(prev_len..text.len());
link_urls.push(link_url);
}
}
Event::Start(tag) => match tag {
Tag::Paragraph => new_paragraph(&mut data.text, &mut list_stack),
Tag::Paragraph => new_paragraph(text, &mut list_stack),
Tag::Heading(_, _, _) => {
new_paragraph(&mut data.text, &mut list_stack);
new_paragraph(text, &mut list_stack);
bold_depth += 1;
}
Tag::CodeBlock(kind) => {
new_paragraph(&mut data.text, &mut list_stack);
new_paragraph(text, &mut list_stack);
current_language = if let CodeBlockKind::Fenced(language) = kind {
language_registry
.language_for_name(language.as_ref())
@ -278,18 +233,18 @@ pub fn render_markdown_mut(
let len = list_stack.len();
if let Some((list_number, has_content)) = list_stack.last_mut() {
*has_content = false;
if !data.text.is_empty() && !data.text.ends_with('\n') {
data.text.push('\n');
if !text.is_empty() && !text.ends_with('\n') {
text.push('\n');
}
for _ in 0..len - 1 {
data.text.push_str(" ");
text.push_str(" ");
}
if let Some(number) = list_number {
data.text.push_str(&format!("{}. ", number));
text.push_str(&format!("{}. ", number));
*number += 1;
*has_content = false;
} else {
data.text.push_str("- ");
text.push_str("- ");
}
}
}
@ -304,8 +259,8 @@ pub fn render_markdown_mut(
Tag::List(_) => drop(list_stack.pop()),
_ => {}
},
Event::HardBreak => data.text.push('\n'),
Event::SoftBreak => data.text.push(' '),
Event::HardBreak => text.push('\n'),
Event::SoftBreak => text.push(' '),
_ => {}
}
}
@ -317,18 +272,35 @@ pub fn render_markdown(
language_registry: &Arc<LanguageRegistry>,
language: Option<&Arc<Language>>,
) -> RichText {
let mut data = RichText {
text: Default::default(),
highlights: Default::default(),
region_ranges: Default::default(),
regions: Default::default(),
};
// let mut data = RichText {
// text: Default::default(),
// highlights: Default::default(),
// region_ranges: Default::default(),
// regions: Default::default(),
// };
render_markdown_mut(&block, mentions, language_registry, language, &mut data);
let mut text = String::new();
let mut highlights = Vec::new();
let mut link_ranges = Vec::new();
let mut link_urls = Vec::new();
render_markdown_mut(
&block,
mentions,
language_registry,
language,
&mut text,
&mut highlights,
&mut link_ranges,
&mut link_urls,
);
text.truncate(text.trim_end().len());
data.text = data.text.trim().to_string();
data
RichText {
text: SharedString::from(text),
link_urls: link_urls.into(),
link_ranges,
highlights,
}
}
pub fn render_code(
@ -339,11 +311,19 @@ pub fn render_code(
) {
let prev_len = text.len();
text.push_str(content);
let mut offset = 0;
for (range, highlight_id) in language.highlight_text(&content.into(), 0..content.len()) {
if range.start > offset {
highlights.push((prev_len + offset..prev_len + range.start, Highlight::Code));
}
highlights.push((
prev_len + range.start..prev_len + range.end,
Highlight::Id(highlight_id),
));
offset = range.end;
}
if offset < content.len() {
highlights.push((prev_len + offset..prev_len + content.len(), Highlight::Code));
}
}

View file

@ -10,7 +10,7 @@ use collections::HashMap;
use editor::{Editor, EditorMode};
use futures::channel::oneshot;
use gpui::{
actions, div, red, Action, AppContext, Div, EventEmitter, FocusableView,
actions, div, impl_actions, red, Action, AppContext, Div, EventEmitter, FocusableView,
InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, Render, Styled,
Subscription, Task, View, ViewContext, VisualContext as _, WeakView, WindowContext,
};
@ -26,12 +26,14 @@ use workspace::{
ToolbarItemLocation, ToolbarItemView,
};
#[derive(PartialEq, Clone, Deserialize, Default, Action)]
#[derive(PartialEq, Clone, Deserialize)]
pub struct Deploy {
pub focus: bool,
}
actions!(Dismiss, FocusEditor);
impl_actions!(buffer_search, [Deploy]);
actions!(buffer_search, [Dismiss, FocusEditor]);
pub enum Event {
UpdateLocation,

View file

@ -22,20 +22,23 @@ pub fn init(cx: &mut AppContext) {
}
actions!(
CycleMode,
ToggleWholeWord,
ToggleCaseSensitive,
ToggleReplace,
SelectNextMatch,
SelectPrevMatch,
SelectAllMatches,
NextHistoryQuery,
PreviousHistoryQuery,
ActivateTextMode,
ActivateSemanticMode,
ActivateRegexMode,
ReplaceAll,
ReplaceNext,
search,
[
CycleMode,
ToggleWholeWord,
ToggleCaseSensitive,
ToggleReplace,
SelectNextMatch,
SelectPrevMatch,
SelectAllMatches,
NextHistoryQuery,
PreviousHistoryQuery,
ActivateTextMode,
ActivateSemanticMode,
ActivateRegexMode,
ReplaceAll,
ReplaceNext,
]
);
bitflags! {

View file

@ -1,7 +1,7 @@
use crate::{settings_store::parse_json_with_comments, SettingsAssets};
use anyhow::{anyhow, Context, Result};
use collections::BTreeMap;
use gpui::{actions, Action, AppContext, KeyBinding, SharedString};
use gpui::{Action, AppContext, KeyBinding, SharedString};
use schemars::{
gen::{SchemaGenerator, SchemaSettings},
schema::{InstanceType, Schema, SchemaObject, SingleOrVec, SubschemaValidation},
@ -137,10 +137,8 @@ impl KeymapFile {
}
}
actions!(NoAction);
fn no_action() -> Box<dyn gpui::Action> {
NoAction.boxed_clone()
gpui::NoAction.boxed_clone()
}
#[cfg(test)]

View file

@ -4,7 +4,7 @@ use gpui::{
};
use ui::prelude::*;
actions!(ActionA, ActionB, ActionC);
actions!(focus, [ActionA, ActionB, ActionC]);
pub struct FocusStory {
child_1_focus: FocusHandle,

View file

@ -59,13 +59,16 @@ use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
use lazy_static::lazy_static;
actions!(
Clear,
Copy,
Paste,
ShowCharacterPalette,
SearchTest,
SendText,
SendKeystroke,
terminal,
[
Clear,
Copy,
Paste,
ShowCharacterPalette,
SearchTest,
SendText,
SendKeystroke,
]
);
///Scrolling is unbearably sluggish by default. Alacritty supports a configurable

View file

@ -5,7 +5,7 @@ use gpui::{
FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
};
use itertools::Itertools;
use language::CursorShape;
@ -27,8 +27,6 @@ use ui::Tooltip;
use std::mem;
use std::{fmt::Debug, ops::RangeInclusive};
use crate::TerminalView;
///The information generated during layout that is necessary for painting
pub struct LayoutState {
cells: Vec<LayoutCell>,
@ -149,7 +147,6 @@ impl LayoutRect {
///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
pub struct TerminalElement {
terminal: Model<Terminal>,
terminal_view: View<TerminalView>,
focus: FocusHandle,
focused: bool,
cursor_visible: bool,
@ -168,7 +165,6 @@ impl StatefulInteractiveElement for TerminalElement {}
impl TerminalElement {
pub fn new(
terminal: Model<Terminal>,
terminal_view: View<TerminalView>,
focus: FocusHandle,
focused: bool,
cursor_visible: bool,
@ -176,7 +172,6 @@ impl TerminalElement {
) -> TerminalElement {
TerminalElement {
terminal,
terminal_view,
focused,
focus: focus.clone(),
cursor_visible,
@ -474,6 +469,7 @@ impl TerminalElement {
.size_full()
.id("terminal-element")
.tooltip(move |cx| Tooltip::text(hovered_word.word.clone(), cx))
.into_any_element()
});
let TerminalContent {
@ -575,7 +571,7 @@ impl TerminalElement {
relative_highlighted_ranges,
mode: *mode,
display_offset: *display_offset,
hyperlink_tooltip: None, // todo!(tooltips)
hyperlink_tooltip,
gutter,
}
}
@ -774,18 +770,11 @@ impl Element for TerminalElement {
(layout_id, interactive_state)
}
fn paint(
mut self,
bounds: Bounds<Pixels>,
state: &mut Self::State,
cx: &mut WindowContext<'_>,
) {
fn paint(self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext<'_>) {
let mut layout = self.compute_layout(bounds, cx);
let theme = cx.theme();
let dispatch_context = self.terminal_view.read(cx).dispatch_context(cx);
self.interactivity().key_context = Some(dispatch_context);
cx.paint_quad(
bounds,
Default::default(),

View file

@ -24,7 +24,7 @@ use anyhow::Result;
const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
actions!(ToggleFocus);
actions!(terminal_view, [ToggleFocus]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(

View file

@ -9,9 +9,10 @@ pub mod terminal_panel;
// use crate::terminal_element::TerminalElement;
use editor::{scroll::autoscroll::Autoscroll, Editor};
use gpui::{
div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle, Focusable,
FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton,
MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
FocusEvent, FocusHandle, Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent,
Keystroke, Model, MouseButton, MouseDownEvent, Pixels, Render, Styled, Subscription, Task,
View, VisualContext, WeakView,
};
use language::Bias;
use persistence::TERMINAL_DB;
@ -54,12 +55,14 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
#[derive(Clone, Debug, PartialEq)]
pub struct ScrollTerminal(pub i32);
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct SendText(String);
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct SendKeystroke(String);
impl_actions!(terminal_view, [SendText, SendKeystroke]);
pub fn init(cx: &mut AppContext) {
terminal_panel::init(cx);
terminal::init(cx);
@ -81,7 +84,7 @@ pub struct TerminalView {
has_new_content: bool,
//Currently using iTerm bell, show bell emoji in tab until input is received
has_bell: bool,
context_menu: Option<View<ContextMenu>>,
context_menu: Option<(View<ContextMenu>, gpui::Point<Pixels>, Subscription)>,
blink_state: bool,
blinking_on: bool,
blinking_paused: bool,
@ -312,14 +315,24 @@ impl TerminalView {
position: gpui::Point<Pixels>,
cx: &mut ViewContext<Self>,
) {
self.context_menu = Some(ContextMenu::build(cx, |menu, cx| {
let context_menu = ContextMenu::build(cx, |menu, cx| {
menu.action("Clear", Box::new(Clear))
.action("Close", Box::new(CloseActiveItem { save_intent: None }))
}));
// todo!(context menus)
// self.context_menu
// .show(position, AnchorCorner::TopLeft, menu_entries, cx);
// cx.notify();
});
cx.focus_view(&context_menu);
let subscription =
cx.subscribe(&context_menu, |this, _, _: &DismissEvent, cx| {
if this.context_menu.as_ref().is_some_and(|context_menu| {
context_menu.0.focus_handle(cx).contains_focused(cx)
}) {
cx.focus_self();
}
this.context_menu.take();
cx.notify();
});
self.context_menu = Some((context_menu, position, subscription));
}
fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
@ -621,7 +634,6 @@ impl Render for TerminalView {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let terminal_handle = self.terminal.clone();
let this_view = cx.view().clone();
let self_id = cx.entity_id();
let focused = self.focus_handle.is_focused(cx);
@ -629,43 +641,41 @@ impl Render for TerminalView {
div()
.size_full()
.relative()
.child(
div()
.z_index(0)
.absolute()
.size_full()
.on_key_down(cx.listener(Self::key_down))
.on_action(cx.listener(TerminalView::send_text))
.on_action(cx.listener(TerminalView::send_keystroke))
.on_action(cx.listener(TerminalView::copy))
.on_action(cx.listener(TerminalView::paste))
.on_action(cx.listener(TerminalView::clear))
.on_action(cx.listener(TerminalView::show_character_palette))
.on_action(cx.listener(TerminalView::select_all))
.child(TerminalElement::new(
terminal_handle,
this_view,
self.focus_handle.clone(),
focused,
self.should_show_cursor(focused, cx),
self.can_navigate_to_selected_word,
))
.on_mouse_down(
MouseButton::Right,
cx.listener(|this, event: &MouseDownEvent, cx| {
this.deploy_context_menu(event.position, cx);
cx.notify();
}),
),
)
.children(
self.context_menu
.clone()
.map(|context_menu| div().z_index(1).absolute().child(context_menu)),
)
.track_focus(&self.focus_handle)
.key_context(self.dispatch_context(cx))
.on_action(cx.listener(TerminalView::send_text))
.on_action(cx.listener(TerminalView::send_keystroke))
.on_action(cx.listener(TerminalView::copy))
.on_action(cx.listener(TerminalView::paste))
.on_action(cx.listener(TerminalView::clear))
.on_action(cx.listener(TerminalView::show_character_palette))
.on_action(cx.listener(TerminalView::select_all))
.on_focus_in(cx.listener(Self::focus_in))
.on_focus_out(cx.listener(Self::focus_out))
.on_key_down(cx.listener(Self::key_down))
.on_mouse_down(
MouseButton::Right,
cx.listener(|this, event: &MouseDownEvent, cx| {
this.deploy_context_menu(event.position, cx);
cx.notify();
}),
)
.child(
// TODO: Oddly this wrapper div is needed for TerminalElement to not steal events from the context menu
div().size_full().child(TerminalElement::new(
terminal_handle,
self.focus_handle.clone(),
focused,
self.should_show_cursor(focused, cx),
self.can_navigate_to_selected_word,
)),
)
.children(self.context_menu.as_ref().map(|(menu, positon, _)| {
overlay()
.position(*positon)
.anchor(gpui::AnchorCorner::TopLeft)
.child(menu.clone())
}))
}
}

View file

@ -10,6 +10,12 @@ use crate::{
SystemColors, Theme, ThemeColors, ThemeFamily, ThemeStyles, UserTheme, UserThemeFamily,
};
#[derive(Debug, Clone)]
pub struct ThemeMeta {
pub name: SharedString,
pub appearance: Appearance,
}
pub struct ThemeRegistry {
themes: HashMap<SharedString, Arc<Theme>>,
}
@ -94,8 +100,11 @@ impl ThemeRegistry {
self.themes.keys().cloned()
}
pub fn list(&self, _staff: bool) -> impl Iterator<Item = SharedString> + '_ {
self.themes.values().map(|theme| theme.name.clone())
pub fn list(&self, _staff: bool) -> impl Iterator<Item = ThemeMeta> + '_ {
self.themes.values().map(|theme| ThemeMeta {
name: theme.name.clone(),
appearance: theme.appearance(),
})
}
pub fn get(&self, name: &str) -> Result<Arc<Theme>> {

View file

@ -31,6 +31,15 @@ pub enum Appearance {
Dark,
}
impl Appearance {
pub fn is_light(&self) -> bool {
match self {
Self::Light => true,
Self::Dark => false,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum LoadThemes {
/// Only load the base theme.

View file

@ -25,7 +25,7 @@ pub fn andromeda() -> UserThemeFamily {
border_selected: Some(rgba(0x1b1d23ff).into()),
border_transparent: Some(rgba(0x1b1d23ff).into()),
border_disabled: Some(rgba(0x1b1d23ff).into()),
elevated_surface_background: Some(rgba(0x23262eff).into()),
elevated_surface_background: Some(rgba(0x2b303bff).into()),
surface_background: Some(rgba(0x23262eff).into()),
background: Some(rgba(0x23262eff).into()),
element_background: Some(rgba(0x00e8c5cc).into()),
@ -33,6 +33,7 @@ pub fn andromeda() -> UserThemeFamily {
element_selected: Some(rgba(0x23262eff).into()),
drop_target_background: Some(rgba(0x3a404eff).into()),
ghost_element_hover: Some(rgba(0x23262eff).into()),
ghost_element_selected: Some(rgba(0x23262eff).into()),
text: Some(rgba(0xd5ced9ff).into()),
status_bar_background: Some(rgba(0x23262eff).into()),
title_bar_background: Some(rgba(0x23262eff).into()),
@ -59,10 +60,13 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xfc644dff).into()),
created: Some(rgba(0x9bc53dbb).into()),
deleted: Some(rgba(0xfc644dbb).into()),
error: Some(rgba(0xfc644dff).into()),
hidden: Some(rgba(0x746f77ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x555555ff).into()),
modified: Some(rgba(0x5bc0ebbb).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -88,6 +92,20 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xee5d43ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xf92672ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -137,6 +155,34 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -154,7 +200,7 @@ pub fn andromeda() -> UserThemeFamily {
(
"type".into(),
UserHighlightStyle {
color: Some(rgba(0xee5d43ff).into()),
color: Some(rgba(0xffe66dff).into()),
..Default::default()
},
),
@ -187,7 +233,7 @@ pub fn andromeda() -> UserThemeFamily {
border_selected: Some(rgba(0x1b1d23ff).into()),
border_transparent: Some(rgba(0x1b1d23ff).into()),
border_disabled: Some(rgba(0x1b1d23ff).into()),
elevated_surface_background: Some(rgba(0x23262eff).into()),
elevated_surface_background: Some(rgba(0x2b303bff).into()),
surface_background: Some(rgba(0x23262eff).into()),
background: Some(rgba(0x262a33ff).into()),
element_background: Some(rgba(0x00e8c5cc).into()),
@ -195,10 +241,11 @@ pub fn andromeda() -> UserThemeFamily {
element_selected: Some(rgba(0x23262eff).into()),
drop_target_background: Some(rgba(0x3a404eff).into()),
ghost_element_hover: Some(rgba(0x23262eff).into()),
ghost_element_selected: Some(rgba(0x23262eff).into()),
text: Some(rgba(0xd5ced9ff).into()),
status_bar_background: Some(rgba(0x23262eff).into()),
title_bar_background: Some(rgba(0x23262eff).into()),
toolbar_background: Some(rgba(0x23262eff).into()),
toolbar_background: Some(rgba(0x262a33ff).into()),
tab_bar_background: Some(rgba(0x23262eff).into()),
tab_inactive_background: Some(rgba(0x23262eff).into()),
tab_active_background: Some(rgba(0x262a33ff).into()),
@ -221,10 +268,13 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xfc644dff).into()),
created: Some(rgba(0x9bc53dbb).into()),
deleted: Some(rgba(0xfc644dbb).into()),
error: Some(rgba(0xfc644dff).into()),
hidden: Some(rgba(0x746f77ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x555555ff).into()),
modified: Some(rgba(0x5bc0ebbb).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -250,6 +300,20 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xee5d43ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xf92672ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -299,6 +363,34 @@ pub fn andromeda() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x96e072ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -316,7 +408,7 @@ pub fn andromeda() -> UserThemeFamily {
(
"type".into(),
UserHighlightStyle {
color: Some(rgba(0xee5d43ff).into()),
color: Some(rgba(0xffe66dff).into()),
..Default::default()
},
),

View file

@ -25,13 +25,14 @@ pub fn ayu() -> UserThemeFamily {
border_selected: Some(rgba(0x6b7d8f1f).into()),
border_transparent: Some(rgba(0x6b7d8f1f).into()),
border_disabled: Some(rgba(0x6b7d8f1f).into()),
elevated_surface_background: Some(rgba(0xf8f9faff).into()),
elevated_surface_background: Some(rgba(0xfcfcfcff).into()),
surface_background: Some(rgba(0xf8f9faff).into()),
background: Some(rgba(0xf8f9faff).into()),
element_background: Some(rgba(0xffaa33ff).into()),
element_hover: Some(rgba(0x56728f1f).into()),
element_selected: Some(rgba(0x56728f1f).into()),
ghost_element_hover: Some(rgba(0x56728f1f).into()),
ghost_element_selected: Some(rgba(0x56728f1f).into()),
text: Some(rgba(0x8a9199ff).into()),
status_bar_background: Some(rgba(0xf8f9faff).into()),
title_bar_background: Some(rgba(0xf8f9faff).into()),
@ -63,10 +64,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xe65050ff).into()),
created: Some(rgba(0x6cbf43cc).into()),
deleted: Some(rgba(0xff7383cc).into()),
error: Some(rgba(0xe65050ff).into()),
hidden: Some(rgba(0x8a9199ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x8a919980).into()),
modified: Some(rgba(0x478acccc).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -104,7 +108,14 @@ pub fn ayu() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x4cbf99ff).into()),
color: Some(rgba(0xa37accff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x55b4d4ff).into()),
..Default::default()
},
),
@ -134,14 +145,14 @@ pub fn ayu() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xf07171ff).into()),
color: Some(rgba(0xf2ae49ff).into()),
..Default::default()
},
),
(
"keyword".into(),
UserHighlightStyle {
color: Some(rgba(0x55b4d4ff).into()),
color: Some(rgba(0xfa8d3eff).into()),
..Default::default()
},
),
@ -183,14 +194,14 @@ pub fn ayu() -> UserThemeFamily {
(
"property".into(),
UserHighlightStyle {
color: Some(rgba(0x55b4d4ff).into()),
color: Some(rgba(0xf07171ff).into()),
..Default::default()
},
),
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x5c6166b3).into()),
color: Some(rgba(0x5c6166ff).into()),
..Default::default()
},
),
@ -215,6 +226,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x5c6166ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -229,6 +247,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x86b300ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
@ -281,7 +306,7 @@ pub fn ayu() -> UserThemeFamily {
(
"variable.special".into(),
UserHighlightStyle {
color: Some(rgba(0xf2ae49ff).into()),
color: Some(rgba(0xf07171ff).into()),
..Default::default()
},
),
@ -300,13 +325,14 @@ pub fn ayu() -> UserThemeFamily {
border_selected: Some(rgba(0x171b24ff).into()),
border_transparent: Some(rgba(0x171b24ff).into()),
border_disabled: Some(rgba(0x171b24ff).into()),
elevated_surface_background: Some(rgba(0x1f2430ff).into()),
elevated_surface_background: Some(rgba(0x242936ff).into()),
surface_background: Some(rgba(0x1f2430ff).into()),
background: Some(rgba(0x1f2430ff).into()),
element_background: Some(rgba(0xffcc66ff).into()),
element_hover: Some(rgba(0x63759926).into()),
element_selected: Some(rgba(0x63759926).into()),
ghost_element_hover: Some(rgba(0x63759926).into()),
ghost_element_selected: Some(rgba(0x63759926).into()),
text: Some(rgba(0x707a8cff).into()),
status_bar_background: Some(rgba(0x1f2430ff).into()),
title_bar_background: Some(rgba(0x1f2430ff).into()),
@ -338,10 +364,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xff6666ff).into()),
created: Some(rgba(0x87d96ccc).into()),
deleted: Some(rgba(0xf27983cc).into()),
error: Some(rgba(0xff6666ff).into()),
hidden: Some(rgba(0x707a8cff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x707a8c80).into()),
modified: Some(rgba(0x80bfffcc).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -379,7 +408,14 @@ pub fn ayu() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x95e6cbff).into()),
color: Some(rgba(0xdfbfffff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x5ccfe6ff).into()),
..Default::default()
},
),
@ -409,14 +445,14 @@ pub fn ayu() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xf28779ff).into()),
color: Some(rgba(0xffd173ff).into()),
..Default::default()
},
),
(
"keyword".into(),
UserHighlightStyle {
color: Some(rgba(0x5ccfe6ff).into()),
color: Some(rgba(0xffad66ff).into()),
..Default::default()
},
),
@ -458,14 +494,14 @@ pub fn ayu() -> UserThemeFamily {
(
"property".into(),
UserHighlightStyle {
color: Some(rgba(0x5ccfe6ff).into()),
color: Some(rgba(0xf28779ff).into()),
..Default::default()
},
),
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0xcccac2b3).into()),
color: Some(rgba(0xcccac2ff).into()),
..Default::default()
},
),
@ -490,6 +526,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xcccac2ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -504,6 +547,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xd5ff80ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
@ -556,7 +606,7 @@ pub fn ayu() -> UserThemeFamily {
(
"variable.special".into(),
UserHighlightStyle {
color: Some(rgba(0xffd173ff).into()),
color: Some(rgba(0xf28779ff).into()),
..Default::default()
},
),
@ -575,13 +625,14 @@ pub fn ayu() -> UserThemeFamily {
border_selected: Some(rgba(0x1e232bff).into()),
border_transparent: Some(rgba(0x1e232bff).into()),
border_disabled: Some(rgba(0x1e232bff).into()),
elevated_surface_background: Some(rgba(0x0b0e14ff).into()),
elevated_surface_background: Some(rgba(0x0d1017ff).into()),
surface_background: Some(rgba(0x0b0e14ff).into()),
background: Some(rgba(0x0b0e14ff).into()),
element_background: Some(rgba(0xe6b450ff).into()),
element_hover: Some(rgba(0x47526640).into()),
element_selected: Some(rgba(0x47526640).into()),
ghost_element_hover: Some(rgba(0x47526640).into()),
ghost_element_selected: Some(rgba(0x47526640).into()),
text: Some(rgba(0x565b66ff).into()),
status_bar_background: Some(rgba(0x0b0e14ff).into()),
title_bar_background: Some(rgba(0x0b0e14ff).into()),
@ -613,10 +664,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xd95757ff).into()),
created: Some(rgba(0x7fd962cc).into()),
deleted: Some(rgba(0xf26d78cc).into()),
error: Some(rgba(0xd95757ff).into()),
hidden: Some(rgba(0x565b66ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x565b6680).into()),
modified: Some(rgba(0x73b8ffcc).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -654,7 +708,14 @@ pub fn ayu() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x95e6cbff).into()),
color: Some(rgba(0xd2a6ffff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x39bae6ff).into()),
..Default::default()
},
),
@ -684,14 +745,14 @@ pub fn ayu() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xf07178ff).into()),
color: Some(rgba(0xffb454ff).into()),
..Default::default()
},
),
(
"keyword".into(),
UserHighlightStyle {
color: Some(rgba(0x39bae6ff).into()),
color: Some(rgba(0xff8f40ff).into()),
..Default::default()
},
),
@ -733,14 +794,14 @@ pub fn ayu() -> UserThemeFamily {
(
"property".into(),
UserHighlightStyle {
color: Some(rgba(0x39bae6ff).into()),
color: Some(rgba(0xf07178ff).into()),
..Default::default()
},
),
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0xbfbdb6b3).into()),
color: Some(rgba(0xbfbdb6ff).into()),
..Default::default()
},
),
@ -765,6 +826,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xbfbdb6ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -779,6 +847,13 @@ pub fn ayu() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xaad94cff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
@ -831,7 +906,7 @@ pub fn ayu() -> UserThemeFamily {
(
"variable.special".into(),
UserHighlightStyle {
color: Some(rgba(0xffb454ff).into()),
color: Some(rgba(0xf07178ff).into()),
..Default::default()
},
),

View file

@ -24,7 +24,7 @@ pub fn dracula() -> UserThemeFamily {
border_selected: Some(rgba(0xbd93f9ff).into()),
border_transparent: Some(rgba(0xbd93f9ff).into()),
border_disabled: Some(rgba(0xbd93f9ff).into()),
elevated_surface_background: Some(rgba(0x282a36ff).into()),
elevated_surface_background: Some(rgba(0x343746ff).into()),
surface_background: Some(rgba(0x282a36ff).into()),
background: Some(rgba(0x282a36ff).into()),
element_background: Some(rgba(0x44475aff).into()),
@ -32,11 +32,12 @@ pub fn dracula() -> UserThemeFamily {
element_selected: Some(rgba(0x44475aff).into()),
drop_target_background: Some(rgba(0x44475aff).into()),
ghost_element_hover: Some(rgba(0x44475a75).into()),
ghost_element_selected: Some(rgba(0x44475aff).into()),
text: Some(rgba(0xf8f8f2ff).into()),
status_bar_background: Some(rgba(0x191a21ff).into()),
title_bar_background: Some(rgba(0x21222cff).into()),
toolbar_background: Some(rgba(0x282a36ff).into()),
tab_bar_background: Some(rgba(0x282a36ff).into()),
tab_bar_background: Some(rgba(0x191a21ff).into()),
tab_inactive_background: Some(rgba(0x21222cff).into()),
tab_active_background: Some(rgba(0x282a36ff).into()),
editor_background: Some(rgba(0x282a36ff).into()),
@ -63,10 +64,14 @@ pub fn dracula() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xff5555ff).into()),
conflict: Some(rgba(0xffb86cff).into()),
created: Some(rgba(0x50fa7b80).into()),
deleted: Some(rgba(0xff555580).into()),
error: Some(rgba(0xff5555ff).into()),
hidden: Some(rgba(0x6272a4ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x6272a4ff).into()),
modified: Some(rgba(0x8be9fd80).into()),
warning: Some(rgba(0xffb86cff).into()),
..Default::default()
},
@ -94,6 +99,20 @@ pub fn dracula() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xbd93f9ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xff79c6ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -138,6 +157,13 @@ pub fn dracula() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0xbd93f9ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -145,6 +171,34 @@ pub fn dracula() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0xf1fa8cff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xf1fa8cff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xf1fa8cff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xf1fa8cff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {

View file

@ -25,15 +25,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0x3c3836ff).into()),
border_transparent: Some(rgba(0x3c3836ff).into()),
border_disabled: Some(rgba(0x3c3836ff).into()),
elevated_surface_background: Some(rgba(0x1d2021ff).into()),
background: Some(rgba(0x1d2021ff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0x3c383680).into()),
element_selected: Some(rgba(0x3c383680).into()),
drop_target_background: Some(rgba(0x3c3836ff).into()),
ghost_element_hover: Some(rgba(0x3c383680).into()),
ghost_element_selected: Some(rgba(0x3c383680).into()),
text: Some(rgba(0xebdbb2ff).into()),
status_bar_background: Some(rgba(0x1d2021ff).into()),
title_bar_background: Some(rgba(0x1d2021ff).into()),
toolbar_background: Some(rgba(0x1d2021ff).into()),
tab_bar_background: Some(rgba(0x1d2021ff).into()),
tab_inactive_background: Some(rgba(0x1d2021ff).into()),
tab_active_background: Some(rgba(0x32302fff).into()),
editor_background: Some(rgba(0x1d2021ff).into()),
@ -60,10 +64,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0xb8bb26ff).into()),
deleted: Some(rgba(0xfb4934ff).into()),
error: Some(rgba(0xfb4934ff).into()),
hidden: Some(rgba(0xa89984ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x7c6f64ff).into()),
modified: Some(rgba(0x83a598ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -91,6 +99,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -102,7 +124,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xfabd2fff).into()),
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
@ -134,6 +156,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -141,6 +170,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xfe8019ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -151,7 +187,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x83a598ff).into()),
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
@ -169,6 +233,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -226,15 +311,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0x3c3836ff).into()),
border_transparent: Some(rgba(0x3c3836ff).into()),
border_disabled: Some(rgba(0x3c3836ff).into()),
elevated_surface_background: Some(rgba(0x282828ff).into()),
background: Some(rgba(0x282828ff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0x3c383680).into()),
element_selected: Some(rgba(0x3c383680).into()),
drop_target_background: Some(rgba(0x3c3836ff).into()),
ghost_element_hover: Some(rgba(0x3c383680).into()),
ghost_element_selected: Some(rgba(0x3c383680).into()),
text: Some(rgba(0xebdbb2ff).into()),
status_bar_background: Some(rgba(0x282828ff).into()),
title_bar_background: Some(rgba(0x282828ff).into()),
toolbar_background: Some(rgba(0x282828ff).into()),
tab_bar_background: Some(rgba(0x282828ff).into()),
tab_inactive_background: Some(rgba(0x282828ff).into()),
tab_active_background: Some(rgba(0x3c3836ff).into()),
editor_background: Some(rgba(0x282828ff).into()),
@ -261,10 +350,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0xb8bb26ff).into()),
deleted: Some(rgba(0xfb4934ff).into()),
error: Some(rgba(0xfb4934ff).into()),
hidden: Some(rgba(0xa89984ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x7c6f64ff).into()),
modified: Some(rgba(0x83a598ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -292,6 +385,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -303,7 +410,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xfabd2fff).into()),
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
@ -335,6 +442,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -342,6 +456,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xfe8019ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -352,7 +473,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x83a598ff).into()),
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
@ -370,6 +519,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -427,15 +597,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0x3c3836ff).into()),
border_transparent: Some(rgba(0x3c3836ff).into()),
border_disabled: Some(rgba(0x3c3836ff).into()),
elevated_surface_background: Some(rgba(0x32302fff).into()),
background: Some(rgba(0x32302fff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0x3c383680).into()),
element_selected: Some(rgba(0x3c383680).into()),
drop_target_background: Some(rgba(0x3c3836ff).into()),
ghost_element_hover: Some(rgba(0x3c383680).into()),
ghost_element_selected: Some(rgba(0x3c383680).into()),
text: Some(rgba(0xebdbb2ff).into()),
status_bar_background: Some(rgba(0x32302fff).into()),
title_bar_background: Some(rgba(0x32302fff).into()),
toolbar_background: Some(rgba(0x32302fff).into()),
tab_bar_background: Some(rgba(0x32302fff).into()),
tab_inactive_background: Some(rgba(0x32302fff).into()),
tab_active_background: Some(rgba(0x504945ff).into()),
editor_background: Some(rgba(0x32302fff).into()),
@ -462,10 +636,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0xb8bb26ff).into()),
deleted: Some(rgba(0xfb4934ff).into()),
error: Some(rgba(0xfb4934ff).into()),
hidden: Some(rgba(0xa89984ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x7c6f64ff).into()),
modified: Some(rgba(0x83a598ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -493,6 +671,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -504,7 +696,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xfabd2fff).into()),
color: Some(rgba(0x8ec07cff).into()),
..Default::default()
},
),
@ -536,6 +728,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0xd3869bff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -543,6 +742,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xfe8019ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -553,7 +759,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x83a598ff).into()),
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xa89984ff).into()),
..Default::default()
},
),
@ -571,6 +805,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xb8bb26ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -628,15 +883,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0xebdbb2ff).into()),
border_transparent: Some(rgba(0xebdbb2ff).into()),
border_disabled: Some(rgba(0xebdbb2ff).into()),
elevated_surface_background: Some(rgba(0xf9f5d7ff).into()),
background: Some(rgba(0xf9f5d7ff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0xebdbb280).into()),
element_selected: Some(rgba(0xebdbb280).into()),
drop_target_background: Some(rgba(0xebdbb2ff).into()),
ghost_element_hover: Some(rgba(0xebdbb280).into()),
ghost_element_selected: Some(rgba(0xebdbb280).into()),
text: Some(rgba(0x3c3836ff).into()),
status_bar_background: Some(rgba(0xf9f5d7ff).into()),
title_bar_background: Some(rgba(0xf9f5d7ff).into()),
toolbar_background: Some(rgba(0xf9f5d7ff).into()),
tab_bar_background: Some(rgba(0xf9f5d7ff).into()),
tab_inactive_background: Some(rgba(0xf9f5d7ff).into()),
tab_active_background: Some(rgba(0xf2e5bcff).into()),
editor_background: Some(rgba(0xf9f5d7ff).into()),
@ -663,10 +922,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0x79740eff).into()),
deleted: Some(rgba(0x9d0006ff).into()),
error: Some(rgba(0x9d0006ff).into()),
hidden: Some(rgba(0x7c6f64ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0xa89984ff).into()),
modified: Some(rgba(0x076678ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -694,6 +957,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -705,7 +982,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xb57614ff).into()),
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
@ -737,6 +1014,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -744,6 +1028,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xaf3a03ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -754,7 +1045,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x076678ff).into()),
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
@ -772,6 +1091,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -829,15 +1169,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0xebdbb2ff).into()),
border_transparent: Some(rgba(0xebdbb2ff).into()),
border_disabled: Some(rgba(0xebdbb2ff).into()),
elevated_surface_background: Some(rgba(0xfbf1c7ff).into()),
background: Some(rgba(0xfbf1c7ff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0xebdbb280).into()),
element_selected: Some(rgba(0xebdbb280).into()),
drop_target_background: Some(rgba(0xebdbb2ff).into()),
ghost_element_hover: Some(rgba(0xebdbb280).into()),
ghost_element_selected: Some(rgba(0xebdbb280).into()),
text: Some(rgba(0x3c3836ff).into()),
status_bar_background: Some(rgba(0xfbf1c7ff).into()),
title_bar_background: Some(rgba(0xfbf1c7ff).into()),
toolbar_background: Some(rgba(0xfbf1c7ff).into()),
tab_bar_background: Some(rgba(0xfbf1c7ff).into()),
tab_inactive_background: Some(rgba(0xfbf1c7ff).into()),
tab_active_background: Some(rgba(0xebdbb2ff).into()),
editor_background: Some(rgba(0xfbf1c7ff).into()),
@ -864,10 +1208,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0x79740eff).into()),
deleted: Some(rgba(0x9d0006ff).into()),
error: Some(rgba(0x9d0006ff).into()),
hidden: Some(rgba(0x7c6f64ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0xa89984ff).into()),
modified: Some(rgba(0x076678ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -895,6 +1243,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -906,7 +1268,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xb57614ff).into()),
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
@ -938,6 +1300,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -945,6 +1314,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xaf3a03ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -955,7 +1331,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x076678ff).into()),
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
@ -973,6 +1377,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -1030,15 +1455,19 @@ pub fn gruvbox() -> UserThemeFamily {
border_selected: Some(rgba(0xebdbb2ff).into()),
border_transparent: Some(rgba(0xebdbb2ff).into()),
border_disabled: Some(rgba(0xebdbb2ff).into()),
elevated_surface_background: Some(rgba(0xf2e5bcff).into()),
background: Some(rgba(0xf2e5bcff).into()),
element_background: Some(rgba(0x45858880).into()),
element_hover: Some(rgba(0xebdbb280).into()),
element_selected: Some(rgba(0xebdbb280).into()),
drop_target_background: Some(rgba(0xebdbb2ff).into()),
ghost_element_hover: Some(rgba(0xebdbb280).into()),
ghost_element_selected: Some(rgba(0xebdbb280).into()),
text: Some(rgba(0x3c3836ff).into()),
status_bar_background: Some(rgba(0xf2e5bcff).into()),
title_bar_background: Some(rgba(0xf2e5bcff).into()),
toolbar_background: Some(rgba(0xf2e5bcff).into()),
tab_bar_background: Some(rgba(0xf2e5bcff).into()),
tab_inactive_background: Some(rgba(0xf2e5bcff).into()),
tab_active_background: Some(rgba(0xd5c4a1ff).into()),
editor_background: Some(rgba(0xf2e5bcff).into()),
@ -1065,10 +1494,14 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb16286ff).into()),
created: Some(rgba(0x79740eff).into()),
deleted: Some(rgba(0x9d0006ff).into()),
error: Some(rgba(0x9d0006ff).into()),
hidden: Some(rgba(0x7c6f64ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0xa89984ff).into()),
modified: Some(rgba(0x076678ff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -1096,6 +1529,20 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
(
"emphasis.strong".into(),
UserHighlightStyle {
@ -1107,7 +1554,7 @@ pub fn gruvbox() -> UserThemeFamily {
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0xb57614ff).into()),
color: Some(rgba(0x427b58ff).into()),
..Default::default()
},
),
@ -1139,6 +1586,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"number".into(),
UserHighlightStyle {
color: Some(rgba(0x8f3f71ff).into()),
..Default::default()
},
),
(
"operator".into(),
UserHighlightStyle {
@ -1146,6 +1600,13 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xaf3a03ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -1156,7 +1617,35 @@ pub fn gruvbox() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x076678ff).into()),
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x7c6f64ff).into()),
..Default::default()
},
),
@ -1174,6 +1663,27 @@ pub fn gruvbox() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x79740eff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {

View file

@ -33,6 +33,7 @@ pub fn night_owl() -> UserThemeFamily {
element_selected: Some(rgba(0x234d708c).into()),
drop_target_background: Some(rgba(0x011627ff).into()),
ghost_element_hover: Some(rgba(0x011627ff).into()),
ghost_element_selected: Some(rgba(0x234d708c).into()),
text: Some(rgba(0xd6deebff).into()),
status_bar_background: Some(rgba(0x011627ff).into()),
title_bar_background: Some(rgba(0x011627ff).into()),
@ -63,10 +64,14 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xffeb95cc).into()),
created: Some(rgba(0x9ccc65ff).into()),
deleted: Some(rgba(0xef5350ff).into()),
error: Some(rgba(0xef5350ff).into()),
hidden: Some(rgba(0x5f7e97ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x395a75ff).into()),
modified: Some(rgba(0xe2b93dff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -109,10 +114,18 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xcaece6ff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0x82aaffff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -148,7 +161,40 @@ pub fn night_owl() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x7fdbcaff).into()),
color: Some(rgba(0xc792eaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -166,6 +212,27 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xecc48dff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xecc48dff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xecc48dff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -190,7 +257,7 @@ pub fn night_owl() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xd7dbe0ff).into()),
color: Some(rgba(0xc5e478ff).into()),
..Default::default()
},
),
@ -223,10 +290,11 @@ pub fn night_owl() -> UserThemeFamily {
element_hover: Some(rgba(0xd3e8f8ff).into()),
element_selected: Some(rgba(0xd3e8f8ff).into()),
ghost_element_hover: Some(rgba(0xd3e8f8ff).into()),
ghost_element_selected: Some(rgba(0xd3e8f8ff).into()),
text: Some(rgba(0x403f53ff).into()),
status_bar_background: Some(rgba(0xf0f0f0ff).into()),
title_bar_background: Some(rgba(0xf0f0f0ff).into()),
toolbar_background: Some(rgba(0xf0f0f0ff).into()),
toolbar_background: Some(rgba(0xfbfbfbff).into()),
tab_bar_background: Some(rgba(0xf0f0f0ff).into()),
tab_inactive_background: Some(rgba(0xf0f0f0ff).into()),
tab_active_background: Some(rgba(0xf6f6f6ff).into()),
@ -254,10 +322,12 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0x403f53ff).into()),
created: Some(rgba(0x49d0c5ff).into()),
deleted: Some(rgba(0xf76e6eff).into()),
error: Some(rgba(0x403f53ff).into()),
hidden: Some(rgba(0x403f53ff).into()),
hint: Some(rgba(0x969696ff).into()),
modified: Some(rgba(0x6fbef6ff).into()),
warning: Some(rgba(0xdaaa01ff).into()),
..Default::default()
},
@ -301,10 +371,18 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
color: Some(rgba(0x4876d6ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -341,6 +419,39 @@ pub fn night_owl() -> UserThemeFamily {
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x994cc3ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -358,6 +469,27 @@ pub fn night_owl() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x4876d6ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x4876d6ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x4876d6ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -382,7 +514,7 @@ pub fn night_owl() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0x403f53ff).into()),
color: Some(rgba(0x4876d6ff).into()),
..Default::default()
},
),

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@ pub fn nord() -> UserThemeFamily {
border_selected: Some(rgba(0x3b4252ff).into()),
border_transparent: Some(rgba(0x3b4252ff).into()),
border_disabled: Some(rgba(0x3b4252ff).into()),
elevated_surface_background: Some(rgba(0x2e3440ff).into()),
elevated_surface_background: Some(rgba(0x3b4252ff).into()),
surface_background: Some(rgba(0x2e3440ff).into()),
background: Some(rgba(0x2e3440ff).into()),
element_background: Some(rgba(0x88c0d0ee).into()),
@ -32,6 +32,7 @@ pub fn nord() -> UserThemeFamily {
element_selected: Some(rgba(0x88c0d0ff).into()),
drop_target_background: Some(rgba(0x88c0d099).into()),
ghost_element_hover: Some(rgba(0x3b4252ff).into()),
ghost_element_selected: Some(rgba(0x88c0d0ff).into()),
text: Some(rgba(0xd8dee9ff).into()),
status_bar_background: Some(rgba(0x3b4252ff).into()),
title_bar_background: Some(rgba(0x2e3440ff).into()),
@ -63,10 +64,14 @@ pub fn nord() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0x5e81acff).into()),
created: Some(rgba(0xa3be8cff).into()),
deleted: Some(rgba(0xbf616aff).into()),
error: Some(rgba(0xbf616aff).into()),
hidden: Some(rgba(0xd8dee966).into()),
hint: Some(rgba(0xd8dee9ff).into()),
ignored: Some(rgba(0xd8dee966).into()),
modified: Some(rgba(0xebcb8bff).into()),
warning: Some(rgba(0xebcb8bff).into()),
..Default::default()
},
@ -103,7 +108,14 @@ pub fn nord() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xebcb8bff).into()),
color: Some(rgba(0x81a1c1ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x81a1c1ff).into()),
..Default::default()
},
),
@ -135,10 +147,24 @@ pub fn nord() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0x5e81acff).into()),
..Default::default()
},
),
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x81a1c1ff).into()),
color: Some(rgba(0xeceff4ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xeceff4ff).into()),
..Default::default()
},
),
@ -149,6 +175,20 @@ pub fn nord() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xeceff4ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xeceff4ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -163,6 +203,27 @@ pub fn nord() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xa3be8cff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xa3be8cff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xa3be8cff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -187,7 +248,7 @@ pub fn nord() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xd8dee9ff).into()),
color: Some(rgba(0x81a1c1ff).into()),
..Default::default()
},
),

View file

@ -33,11 +33,12 @@ pub fn palenight() -> UserThemeFamily {
element_selected: Some(rgba(0x7e57c2ff).into()),
drop_target_background: Some(rgba(0x2e3245ff).into()),
ghost_element_hover: Some(rgba(0x0000001a).into()),
ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
text: Some(rgba(0xffffffff).into()),
status_bar_background: Some(rgba(0x282c3dff).into()),
title_bar_background: Some(rgba(0x292d3eff).into()),
toolbar_background: Some(rgba(0x292d3eff).into()),
tab_bar_background: Some(rgba(0x292d3eff).into()),
tab_bar_background: Some(rgba(0x31364aff).into()),
tab_inactive_background: Some(rgba(0x31364aff).into()),
tab_active_background: Some(rgba(0x292d3eff).into()),
editor_background: Some(rgba(0x292d3eff).into()),
@ -63,10 +64,14 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xffeb95cc).into()),
created: Some(rgba(0x9ccc65ff).into()),
deleted: Some(rgba(0xef5350ff).into()),
error: Some(rgba(0xef5350ff).into()),
hidden: Some(rgba(0x929ac9ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x69709890).into()),
modified: Some(rgba(0xe2b93dff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -108,6 +113,13 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -176,7 +188,35 @@ pub fn palenight() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x89ddffff).into()),
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
@ -194,6 +234,27 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -218,7 +279,7 @@ pub fn palenight() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
color: Some(rgba(0xffcb6bff).into()),
..Default::default()
},
),
@ -252,11 +313,12 @@ pub fn palenight() -> UserThemeFamily {
element_selected: Some(rgba(0x7e57c2ff).into()),
drop_target_background: Some(rgba(0x2e3245ff).into()),
ghost_element_hover: Some(rgba(0x0000001a).into()),
ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
text: Some(rgba(0xffffffff).into()),
status_bar_background: Some(rgba(0x282c3dff).into()),
title_bar_background: Some(rgba(0x292d3eff).into()),
toolbar_background: Some(rgba(0x292d3eff).into()),
tab_bar_background: Some(rgba(0x292d3eff).into()),
tab_bar_background: Some(rgba(0x31364aff).into()),
tab_inactive_background: Some(rgba(0x31364aff).into()),
tab_active_background: Some(rgba(0x292d3eff).into()),
editor_background: Some(rgba(0x292d3eff).into()),
@ -282,10 +344,14 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xffeb95cc).into()),
created: Some(rgba(0x9ccc65ff).into()),
deleted: Some(rgba(0xef5350ff).into()),
error: Some(rgba(0xef5350ff).into()),
hidden: Some(rgba(0x929ac9ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x69709890).into()),
modified: Some(rgba(0xe2b93dff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -327,6 +393,13 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -395,7 +468,35 @@ pub fn palenight() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x89ddffff).into()),
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
@ -413,6 +514,27 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -437,7 +559,7 @@ pub fn palenight() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
color: Some(rgba(0xffcb6bff).into()),
..Default::default()
},
),
@ -463,7 +585,7 @@ pub fn palenight() -> UserThemeFamily {
border_selected: Some(rgba(0x2c2f40ff).into()),
border_transparent: Some(rgba(0x2c2f40ff).into()),
border_disabled: Some(rgba(0x2c2f40ff).into()),
elevated_surface_background: Some(rgba(0x25293aff).into()),
elevated_surface_background: Some(rgba(0x292d3eff).into()),
surface_background: Some(rgba(0x25293aff).into()),
background: Some(rgba(0x292d3eff).into()),
element_background: Some(rgba(0x7e57c2cc).into()),
@ -471,11 +593,12 @@ pub fn palenight() -> UserThemeFamily {
element_selected: Some(rgba(0x7e57c2ff).into()),
drop_target_background: Some(rgba(0x2e3245ff).into()),
ghost_element_hover: Some(rgba(0x0000001a).into()),
ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
text: Some(rgba(0xffffffff).into()),
status_bar_background: Some(rgba(0x25293aff).into()),
title_bar_background: Some(rgba(0x25293aff).into()),
toolbar_background: Some(rgba(0x25293aff).into()),
tab_bar_background: Some(rgba(0x25293aff).into()),
toolbar_background: Some(rgba(0x292d3eff).into()),
tab_bar_background: Some(rgba(0x31364aff).into()),
tab_inactive_background: Some(rgba(0x31364aff).into()),
tab_active_background: Some(rgba(0x25293aff).into()),
editor_background: Some(rgba(0x292d3eff).into()),
@ -501,10 +624,14 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xffeb95cc).into()),
created: Some(rgba(0x9ccc65ff).into()),
deleted: Some(rgba(0xef5350ff).into()),
error: Some(rgba(0xef5350ff).into()),
hidden: Some(rgba(0x929ac9ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0x69709890).into()),
modified: Some(rgba(0xe2b93dff).into()),
..Default::default()
},
syntax: Some(UserSyntaxTheme {
@ -546,6 +673,13 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
..Default::default()
},
),
(
"emphasis".into(),
UserHighlightStyle {
@ -614,7 +748,35 @@ pub fn palenight() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x89ddffff).into()),
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc792eaff).into()),
..Default::default()
},
),
@ -632,6 +794,27 @@ pub fn palenight() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xc3e88dff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -656,7 +839,7 @@ pub fn palenight() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xff5572ff).into()),
color: Some(rgba(0xffcb6bff).into()),
..Default::default()
},
),

View file

@ -19,12 +19,12 @@ pub fn rose_pine() -> UserThemeFamily {
appearance: Appearance::Dark,
styles: UserThemeStylesRefinement {
colors: ThemeColorsRefinement {
border: Some(rgba(0x000000ff).into()),
border_variant: Some(rgba(0x000000ff).into()),
border: Some(rgba(0x00000000).into()),
border_variant: Some(rgba(0x00000000).into()),
border_focused: Some(rgba(0x6e6a8633).into()),
border_selected: Some(rgba(0x000000ff).into()),
border_transparent: Some(rgba(0x000000ff).into()),
border_disabled: Some(rgba(0x000000ff).into()),
border_selected: Some(rgba(0x00000000).into()),
border_transparent: Some(rgba(0x00000000).into()),
border_disabled: Some(rgba(0x00000000).into()),
elevated_surface_background: Some(rgba(0x1f1d2eff).into()),
surface_background: Some(rgba(0x1f1d2eff).into()),
background: Some(rgba(0x191724ff).into()),
@ -33,12 +33,13 @@ pub fn rose_pine() -> UserThemeFamily {
element_selected: Some(rgba(0x6e6a8633).into()),
drop_target_background: Some(rgba(0x1f1d2eff).into()),
ghost_element_hover: Some(rgba(0x6e6a861a).into()),
ghost_element_selected: Some(rgba(0x6e6a8633).into()),
text: Some(rgba(0xe0def4ff).into()),
status_bar_background: Some(rgba(0x191724ff).into()),
title_bar_background: Some(rgba(0x191724ff).into()),
toolbar_background: Some(rgba(0x1f1d2eff).into()),
tab_bar_background: Some(rgba(0x1f1d2eff).into()),
tab_inactive_background: Some(rgba(0x000000ff).into()),
toolbar_background: Some(rgba(0x191724ff).into()),
tab_bar_background: Some(rgba(0x00000000).into()),
tab_inactive_background: Some(rgba(0x00000000).into()),
tab_active_background: Some(rgba(0x6e6a861a).into()),
editor_background: Some(rgba(0x191724ff).into()),
editor_gutter_background: Some(rgba(0x191724ff).into()),
@ -63,10 +64,14 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xeb6f92ff).into()),
created: Some(rgba(0x9ccfd8ff).into()),
deleted: Some(rgba(0xeb6f92ff).into()),
error: Some(rgba(0xeb6f92ff).into()),
hidden: Some(rgba(0x908caaff).into()),
hint: Some(rgba(0x908caaff).into()),
ignored: Some(rgba(0x6e6a86ff).into()),
modified: Some(rgba(0xebbcbaff).into()),
warning: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
@ -103,6 +108,20 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x31748fff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x9ccfd8ff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
@ -134,7 +153,35 @@ pub fn rose_pine() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x6e6a86ff).into()),
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
@ -145,6 +192,34 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -176,7 +251,8 @@ pub fn rose_pine() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xc4a7e7ff).into()),
color: Some(rgba(0xebbcbaff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -196,12 +272,12 @@ pub fn rose_pine() -> UserThemeFamily {
appearance: Appearance::Dark,
styles: UserThemeStylesRefinement {
colors: ThemeColorsRefinement {
border: Some(rgba(0x000000ff).into()),
border_variant: Some(rgba(0x000000ff).into()),
border: Some(rgba(0x00000000).into()),
border_variant: Some(rgba(0x00000000).into()),
border_focused: Some(rgba(0x817c9c26).into()),
border_selected: Some(rgba(0x000000ff).into()),
border_transparent: Some(rgba(0x000000ff).into()),
border_disabled: Some(rgba(0x000000ff).into()),
border_selected: Some(rgba(0x00000000).into()),
border_transparent: Some(rgba(0x00000000).into()),
border_disabled: Some(rgba(0x00000000).into()),
elevated_surface_background: Some(rgba(0x2a273fff).into()),
surface_background: Some(rgba(0x2a273fff).into()),
background: Some(rgba(0x232136ff).into()),
@ -210,12 +286,13 @@ pub fn rose_pine() -> UserThemeFamily {
element_selected: Some(rgba(0x817c9c26).into()),
drop_target_background: Some(rgba(0x2a273fff).into()),
ghost_element_hover: Some(rgba(0x817c9c14).into()),
ghost_element_selected: Some(rgba(0x817c9c26).into()),
text: Some(rgba(0xe0def4ff).into()),
status_bar_background: Some(rgba(0x232136ff).into()),
title_bar_background: Some(rgba(0x232136ff).into()),
toolbar_background: Some(rgba(0x2a273fff).into()),
tab_bar_background: Some(rgba(0x2a273fff).into()),
tab_inactive_background: Some(rgba(0x000000ff).into()),
toolbar_background: Some(rgba(0x232136ff).into()),
tab_bar_background: Some(rgba(0x00000000).into()),
tab_inactive_background: Some(rgba(0x00000000).into()),
tab_active_background: Some(rgba(0x817c9c14).into()),
editor_background: Some(rgba(0x232136ff).into()),
editor_gutter_background: Some(rgba(0x232136ff).into()),
@ -240,10 +317,14 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xeb6f92ff).into()),
created: Some(rgba(0x9ccfd8ff).into()),
deleted: Some(rgba(0xeb6f92ff).into()),
error: Some(rgba(0xeb6f92ff).into()),
hidden: Some(rgba(0x908caaff).into()),
hint: Some(rgba(0x908caaff).into()),
ignored: Some(rgba(0x6e6a86ff).into()),
modified: Some(rgba(0xea9a97ff).into()),
warning: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
@ -280,6 +361,20 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x3e8fb0ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x9ccfd8ff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
@ -311,7 +406,35 @@ pub fn rose_pine() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x6e6a86ff).into()),
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x908caaff).into()),
..Default::default()
},
),
@ -322,6 +445,34 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xf6c177ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -353,7 +504,8 @@ pub fn rose_pine() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xc4a7e7ff).into()),
color: Some(rgba(0xea9a97ff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),
@ -373,12 +525,12 @@ pub fn rose_pine() -> UserThemeFamily {
appearance: Appearance::Light,
styles: UserThemeStylesRefinement {
colors: ThemeColorsRefinement {
border: Some(rgba(0x000000ff).into()),
border_variant: Some(rgba(0x000000ff).into()),
border: Some(rgba(0x00000000).into()),
border_variant: Some(rgba(0x00000000).into()),
border_focused: Some(rgba(0x6e6a8614).into()),
border_selected: Some(rgba(0x000000ff).into()),
border_transparent: Some(rgba(0x000000ff).into()),
border_disabled: Some(rgba(0x000000ff).into()),
border_selected: Some(rgba(0x00000000).into()),
border_transparent: Some(rgba(0x00000000).into()),
border_disabled: Some(rgba(0x00000000).into()),
elevated_surface_background: Some(rgba(0xfffaf3ff).into()),
surface_background: Some(rgba(0xfffaf3ff).into()),
background: Some(rgba(0xfaf4edff).into()),
@ -387,12 +539,13 @@ pub fn rose_pine() -> UserThemeFamily {
element_selected: Some(rgba(0x6e6a8614).into()),
drop_target_background: Some(rgba(0xfffaf3ff).into()),
ghost_element_hover: Some(rgba(0x6e6a860d).into()),
ghost_element_selected: Some(rgba(0x6e6a8614).into()),
text: Some(rgba(0x575279ff).into()),
status_bar_background: Some(rgba(0xfaf4edff).into()),
title_bar_background: Some(rgba(0xfaf4edff).into()),
toolbar_background: Some(rgba(0xfffaf3ff).into()),
tab_bar_background: Some(rgba(0xfffaf3ff).into()),
tab_inactive_background: Some(rgba(0x000000ff).into()),
toolbar_background: Some(rgba(0xfaf4edff).into()),
tab_bar_background: Some(rgba(0x00000000).into()),
tab_inactive_background: Some(rgba(0x00000000).into()),
tab_active_background: Some(rgba(0x6e6a860d).into()),
editor_background: Some(rgba(0xfaf4edff).into()),
editor_gutter_background: Some(rgba(0xfaf4edff).into()),
@ -417,10 +570,14 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
conflict: Some(rgba(0xb4637aff).into()),
created: Some(rgba(0x56949fff).into()),
deleted: Some(rgba(0xb4637aff).into()),
error: Some(rgba(0xb4637aff).into()),
hidden: Some(rgba(0x797593ff).into()),
hint: Some(rgba(0x797593ff).into()),
ignored: Some(rgba(0x9893a5ff).into()),
modified: Some(rgba(0xd7827eff).into()),
warning: Some(rgba(0xea9d34ff).into()),
..Default::default()
},
@ -457,6 +614,20 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0x286983ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x56949fff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
@ -488,7 +659,35 @@ pub fn rose_pine() -> UserThemeFamily {
(
"punctuation".into(),
UserHighlightStyle {
color: Some(rgba(0x9893a5ff).into()),
color: Some(rgba(0x797593ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x797593ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x797593ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x797593ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x797593ff).into()),
..Default::default()
},
),
@ -499,6 +698,34 @@ pub fn rose_pine() -> UserThemeFamily {
..Default::default()
},
),
(
"string.escape".into(),
UserHighlightStyle {
color: Some(rgba(0xea9d34ff).into()),
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0xea9d34ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0xea9d34ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0xea9d34ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -530,7 +757,8 @@ pub fn rose_pine() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0x907aa9ff).into()),
color: Some(rgba(0xd7827eff).into()),
font_style: Some(UserFontStyle::Italic),
..Default::default()
},
),

View file

@ -25,15 +25,19 @@ pub fn solarized() -> UserThemeFamily {
border_selected: Some(rgba(0x003847ff).into()),
border_transparent: Some(rgba(0x003847ff).into()),
border_disabled: Some(rgba(0x003847ff).into()),
elevated_surface_background: Some(rgba(0x00212bff).into()),
background: Some(rgba(0x002b36ff).into()),
element_background: Some(rgba(0x2aa19899).into()),
element_hover: Some(rgba(0x004454aa).into()),
element_selected: Some(rgba(0x005a6fff).into()),
drop_target_background: Some(rgba(0x00445488).into()),
ghost_element_hover: Some(rgba(0x004454aa).into()),
ghost_element_selected: Some(rgba(0x005a6fff).into()),
text: Some(rgba(0xbbbbbbff).into()),
status_bar_background: Some(rgba(0x00212bff).into()),
title_bar_background: Some(rgba(0x002c39ff).into()),
toolbar_background: Some(rgba(0x002b36ff).into()),
tab_bar_background: Some(rgba(0x004052ff).into()),
tab_inactive_background: Some(rgba(0x004052ff).into()),
tab_active_background: Some(rgba(0x002b37ff).into()),
editor_background: Some(rgba(0x002b36ff).into()),
@ -58,7 +62,6 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xffeaeaff).into()),
error: Some(rgba(0xffeaeaff).into()),
hidden: Some(rgba(0x93a1a1ff).into()),
hint: Some(rgba(0x969696ff).into()),
@ -99,7 +102,14 @@ pub fn solarized() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xcb4b16ff).into()),
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x268bd2ff).into()),
..Default::default()
},
),
@ -134,7 +144,7 @@ pub fn solarized() -> UserThemeFamily {
(
"keyword".into(),
UserHighlightStyle {
color: Some(rgba(0x268bd2ff).into()),
color: Some(rgba(0x859900ff).into()),
..Default::default()
},
),
@ -145,6 +155,13 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),
(
"property".into(),
UserHighlightStyle {
@ -159,6 +176,34 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x657b83ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x657b83ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x657b83ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x657b83ff).into()),
..Default::default()
},
),
(
"string".into(),
UserHighlightStyle {
@ -173,6 +218,27 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -190,14 +256,14 @@ pub fn solarized() -> UserThemeFamily {
(
"type".into(),
UserHighlightStyle {
color: Some(rgba(0x859900ff).into()),
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0x839496ff).into()),
color: Some(rgba(0x268bd2ff).into()),
..Default::default()
},
),
@ -223,14 +289,18 @@ pub fn solarized() -> UserThemeFamily {
border_selected: Some(rgba(0xddd6c1ff).into()),
border_transparent: Some(rgba(0xddd6c1ff).into()),
border_disabled: Some(rgba(0xddd6c1ff).into()),
elevated_surface_background: Some(rgba(0xeee8d5ff).into()),
background: Some(rgba(0xfdf6e3ff).into()),
element_background: Some(rgba(0xac9d57ff).into()),
element_hover: Some(rgba(0xdfca8844).into()),
element_selected: Some(rgba(0xdfca88ff).into()),
ghost_element_hover: Some(rgba(0xdfca8844).into()),
ghost_element_selected: Some(rgba(0xdfca88ff).into()),
text: Some(rgba(0x333333ff).into()),
status_bar_background: Some(rgba(0xeee8d5ff).into()),
title_bar_background: Some(rgba(0xeee8d5ff).into()),
toolbar_background: Some(rgba(0xfdf6e3ff).into()),
tab_bar_background: Some(rgba(0xd9d2c2ff).into()),
tab_inactive_background: Some(rgba(0xd3cbb7ff).into()),
tab_active_background: Some(rgba(0xfdf6e3ff).into()),
editor_background: Some(rgba(0xfdf6e3ff).into()),
@ -294,7 +364,14 @@ pub fn solarized() -> UserThemeFamily {
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xcb4b16ff).into()),
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x268bd2ff).into()),
..Default::default()
},
),
@ -329,7 +406,7 @@ pub fn solarized() -> UserThemeFamily {
(
"keyword".into(),
UserHighlightStyle {
color: Some(rgba(0x268bd2ff).into()),
color: Some(rgba(0x859900ff).into()),
..Default::default()
},
),
@ -340,6 +417,13 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
),
(
"preproc".into(),
UserHighlightStyle {
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
@ -361,6 +445,27 @@ pub fn solarized() -> UserThemeFamily {
..Default::default()
},
),
(
"string.regex".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"string.special".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"string.special.symbol".into(),
UserHighlightStyle {
color: Some(rgba(0x2aa198ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -378,7 +483,7 @@ pub fn solarized() -> UserThemeFamily {
(
"type".into(),
UserHighlightStyle {
color: Some(rgba(0x859900ff).into()),
color: Some(rgba(0xb58900ff).into()),
..Default::default()
},
),

View file

@ -19,15 +19,19 @@ pub fn synthwave_84() -> UserThemeFamily {
styles: UserThemeStylesRefinement {
colors: ThemeColorsRefinement {
border_focused: Some(rgba(0x1f212bff).into()),
elevated_surface_background: Some(rgba(0x232530ff).into()),
background: Some(rgba(0x262335ff).into()),
element_background: Some(rgba(0x614d85ff).into()),
element_hover: Some(rgba(0x37294d99).into()),
element_selected: Some(rgba(0xffffff20).into()),
drop_target_background: Some(rgba(0x34294f66).into()),
ghost_element_hover: Some(rgba(0x37294d99).into()),
ghost_element_selected: Some(rgba(0xffffff20).into()),
text: Some(rgba(0xffffffff).into()),
status_bar_background: Some(rgba(0x241b2fff).into()),
title_bar_background: Some(rgba(0x241b2fff).into()),
toolbar_background: Some(rgba(0x262335ff).into()),
tab_bar_background: Some(rgba(0x241b2fff).into()),
tab_inactive_background: Some(rgba(0x262335ff).into()),
editor_background: Some(rgba(0x262335ff).into()),
editor_gutter_background: Some(rgba(0x262335ff).into()),
@ -47,9 +51,12 @@ pub fn synthwave_84() -> UserThemeFamily {
..Default::default()
},
status: StatusColorsRefinement {
deleted: Some(rgba(0xfe4450ff).into()),
created: Some(rgba(0x206d4bd6).into()),
deleted: Some(rgba(0xfa2e46a4).into()),
error: Some(rgba(0xfe4450ff).into()),
hint: Some(rgba(0x969696ff).into()),
ignored: Some(rgba(0xffffff59).into()),
modified: Some(rgba(0xb893ce8f).into()),
warning: Some(rgba(0x72f1b8bb).into()),
..Default::default()
},
@ -85,6 +92,20 @@ pub fn synthwave_84() -> UserThemeFamily {
..Default::default()
},
),
(
"constant".into(),
UserHighlightStyle {
color: Some(rgba(0xf97e72ff).into()),
..Default::default()
},
),
(
"constructor".into(),
UserHighlightStyle {
color: Some(rgba(0x72f1b8ff).into()),
..Default::default()
},
),
(
"function".into(),
UserHighlightStyle {
@ -148,6 +169,34 @@ pub fn synthwave_84() -> UserThemeFamily {
..Default::default()
},
),
(
"punctuation.bracket".into(),
UserHighlightStyle {
color: Some(rgba(0x36f9f6ff).into()),
..Default::default()
},
),
(
"punctuation.delimiter".into(),
UserHighlightStyle {
color: Some(rgba(0x36f9f6ff).into()),
..Default::default()
},
),
(
"punctuation.list_marker".into(),
UserHighlightStyle {
color: Some(rgba(0x36f9f6ff).into()),
..Default::default()
},
),
(
"punctuation.special".into(),
UserHighlightStyle {
color: Some(rgba(0x36f9f6ff).into()),
..Default::default()
},
),
(
"tag".into(),
UserHighlightStyle {
@ -172,8 +221,7 @@ pub fn synthwave_84() -> UserThemeFamily {
(
"variable".into(),
UserHighlightStyle {
color: Some(rgba(0xfe4450ff).into()),
font_weight: Some(UserFontWeight(700.0)),
color: Some(rgba(0xff7edbff).into()),
..Default::default()
},
),

View file

@ -75,10 +75,20 @@ impl VsCodeThemeConverter {
};
Ok(StatusColorsRefinement {
// conflict: None,
// created: None,
created: vscode_colors
.editor_gutter_added_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
modified: vscode_colors
.editor_gutter_modified_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
deleted: vscode_colors
.error_foreground
.editor_gutter_deleted_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
conflict: vscode_colors
.git_decoration_conflicting_resource_foreground
.as_ref()
.traverse(|color| try_parse_color(&color))?,
error: vscode_colors
@ -94,9 +104,11 @@ impl VsCodeThemeConverter {
.as_ref()
.traverse(|color| try_parse_color(&color))?
.or(vscode_base_status_colors.hint),
// ignored: None,
ignored: vscode_colors
.git_decoration_ignored_resource_foreground
.as_ref()
.traverse(|color| try_parse_color(&color))?,
// info: None,
// modified: None,
// renamed: None,
// success: None,
warning: vscode_colors
@ -110,6 +122,11 @@ impl VsCodeThemeConverter {
fn convert_theme_colors(&self) -> Result<ThemeColorsRefinement> {
let vscode_colors = &self.theme.colors;
let vscode_editor_background = vscode_colors
.editor_background
.as_ref()
.traverse(|color| try_parse_color(&color))?;
Ok(ThemeColorsRefinement {
border: vscode_colors
.panel_border
@ -136,17 +153,14 @@ impl VsCodeThemeConverter {
.as_ref()
.traverse(|color| try_parse_color(&color))?,
elevated_surface_background: vscode_colors
.panel_background
.dropdown_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
surface_background: vscode_colors
.panel_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
background: vscode_colors
.editor_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
background: vscode_editor_background,
title_bar_background: vscode_colors
.title_bar_active_background
.as_ref()
@ -171,6 +185,10 @@ impl VsCodeThemeConverter {
.list_hover_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
ghost_element_selected: vscode_colors
.list_active_selection_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
drop_target_background: vscode_colors
.list_drop_background
.as_ref()
@ -190,7 +208,7 @@ impl VsCodeThemeConverter {
.flatten()
}),
tab_bar_background: vscode_colors
.panel_background
.editor_group_header_tabs_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
tab_active_background: vscode_colors
@ -202,17 +220,12 @@ impl VsCodeThemeConverter {
.as_ref()
.traverse(|color| try_parse_color(&color))?,
toolbar_background: vscode_colors
.panel_background
.breadcrumb_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
editor_background: vscode_colors
.editor_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
editor_gutter_background: vscode_colors
.editor_background
.as_ref()
.traverse(|color| try_parse_color(&color))?,
.traverse(|color| try_parse_color(&color))?
.or(vscode_editor_background),
editor_background: vscode_editor_background,
editor_gutter_background: vscode_editor_background,
editor_line_number: vscode_colors
.editor_line_number_foreground
.as_ref()

View file

@ -153,11 +153,20 @@ impl ZedSyntaxToken {
.map(|scope| scope.as_str())
.collect::<Vec<_>>();
let scopes_to_match = self.to_vscode();
let number_of_scopes_to_match = scopes_to_match.len();
let mut matches = 0;
for scope in self.to_vscode() {
for (ix, scope) in scopes_to_match.into_iter().enumerate() {
// Assign each entry a weight that is inversely proportional to its
// position in the list.
//
// Entries towards the front are weighted higher than those towards the end.
let weight = (number_of_scopes_to_match - ix) as u32;
if candidate_scopes.contains(&scope) {
matches += 1;
matches += 1 + weight;
}
}
@ -167,7 +176,16 @@ impl ZedSyntaxToken {
pub fn fallbacks(&self) -> &[Self] {
match self {
ZedSyntaxToken::CommentDoc => &[ZedSyntaxToken::Comment],
ZedSyntaxToken::Number => &[ZedSyntaxToken::Constant],
ZedSyntaxToken::VariableSpecial => &[ZedSyntaxToken::Variable],
ZedSyntaxToken::PunctuationBracket
| ZedSyntaxToken::PunctuationDelimiter
| ZedSyntaxToken::PunctuationListMarker
| ZedSyntaxToken::PunctuationSpecial => &[ZedSyntaxToken::Punctuation],
ZedSyntaxToken::StringEscape
| ZedSyntaxToken::StringRegex
| ZedSyntaxToken::StringSpecial
| ZedSyntaxToken::StringSpecialSymbol => &[ZedSyntaxToken::String],
_ => &[],
}
}
@ -178,9 +196,12 @@ impl ZedSyntaxToken {
ZedSyntaxToken::Boolean => vec!["constant.language"],
ZedSyntaxToken::Comment => vec!["comment"],
ZedSyntaxToken::CommentDoc => vec!["comment.block.documentation"],
ZedSyntaxToken::Constant => vec!["constant.character"],
ZedSyntaxToken::Constant => vec!["constant", "constant.language", "constant.character"],
ZedSyntaxToken::Constructor => {
vec!["entity.name.function.definition.special.constructor"]
vec![
"entity.name.tag",
"entity.name.function.definition.special.constructor",
]
}
ZedSyntaxToken::Embedded => vec!["meta.embedded"],
ZedSyntaxToken::Emphasis => vec!["markup.italic"],
@ -191,16 +212,17 @@ impl ZedSyntaxToken {
],
ZedSyntaxToken::Enum => vec!["support.type.enum"],
ZedSyntaxToken::Function => vec![
"entity.function",
"entity.name.function",
"variable.function",
"support.function",
],
ZedSyntaxToken::Hint => vec![],
ZedSyntaxToken::Keyword => vec![
"keyword",
"keyword.other.fn.rust",
"keyword.control",
"keyword.control.fun",
"keyword.other.fn.rust",
"keyword.control.class",
"punctuation.accessor",
"entity.name.tag",
],
@ -215,7 +237,11 @@ impl ZedSyntaxToken {
ZedSyntaxToken::Number => vec!["constant.numeric", "number"],
ZedSyntaxToken::Operator => vec!["operator", "keyword.operator"],
ZedSyntaxToken::Predictive => vec![],
ZedSyntaxToken::Preproc => vec!["preproc"],
ZedSyntaxToken::Preproc => vec![
"preproc",
"meta.preprocessor",
"punctuation.definition.preprocessor",
],
ZedSyntaxToken::Primary => vec![],
ZedSyntaxToken::Property => vec![
"variable.member",
@ -228,7 +254,6 @@ impl ZedSyntaxToken {
"punctuation.section",
"punctuation.accessor",
"punctuation.separator",
"punctuation.terminator",
"punctuation.definition.tag",
],
ZedSyntaxToken::PunctuationBracket => vec![

File diff suppressed because it is too large Load diff

View file

@ -2,18 +2,18 @@ use feature_flags::FeatureFlagAppExt;
use fs::Fs;
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
use gpui::{
actions, AppContext, DismissEvent, Div, EventEmitter, FocusableView, Render, SharedString,
View, ViewContext, VisualContext, WeakView,
actions, AppContext, DismissEvent, Div, EventEmitter, FocusableView, Render, View, ViewContext,
VisualContext, WeakView,
};
use picker::{Picker, PickerDelegate};
use settings::{update_settings_file, SettingsStore};
use std::sync::Arc;
use theme::{Theme, ThemeRegistry, ThemeSettings};
use theme::{Theme, ThemeMeta, ThemeRegistry, ThemeSettings};
use ui::{prelude::*, v_stack, ListItem};
use util::ResultExt;
use workspace::{ui::HighlightedLabel, Workspace};
use workspace::{ui::HighlightedLabel, ModalView, Workspace};
actions!(Toggle, Reload);
actions!(theme_selector, [Toggle, Reload]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(
@ -52,6 +52,8 @@ pub fn reload(cx: &mut AppContext) {
}
}
impl ModalView for ThemeSelector {}
pub struct ThemeSelector {
picker: View<Picker<ThemeSelectorDelegate>>,
}
@ -81,7 +83,7 @@ impl ThemeSelector {
pub struct ThemeSelectorDelegate {
fs: Arc<dyn Fs>,
theme_names: Vec<SharedString>,
themes: Vec<ThemeMeta>,
matches: Vec<StringMatch>,
original_theme: Arc<Theme>,
selection_completed: bool,
@ -99,21 +101,25 @@ impl ThemeSelectorDelegate {
let staff_mode = cx.is_staff();
let registry = cx.global::<ThemeRegistry>();
let theme_names = registry.list(staff_mode).collect::<Vec<_>>();
//todo!(theme sorting)
// theme_names.sort_unstable_by(|a, b| a.is_light.cmp(&b.is_light).then(a.name.cmp(&b.name)));
let matches = theme_names
let mut themes = registry.list(staff_mode).collect::<Vec<_>>();
themes.sort_unstable_by(|a, b| {
a.appearance
.is_light()
.cmp(&b.appearance.is_light())
.then(a.name.cmp(&b.name))
});
let matches = themes
.iter()
.map(|meta| StringMatch {
candidate_id: 0,
score: 0.0,
positions: Default::default(),
string: meta.to_string(),
string: meta.name.to_string(),
})
.collect();
let mut this = Self {
fs,
theme_names,
themes,
matches,
original_theme: original_theme.clone(),
selected_index: 0,
@ -213,13 +219,13 @@ impl PickerDelegate for ThemeSelectorDelegate {
) -> gpui::Task<()> {
let background = cx.background_executor().clone();
let candidates = self
.theme_names
.themes
.iter()
.enumerate()
.map(|(id, meta)| StringMatchCandidate {
id,
char_bag: meta.as_ref().into(),
string: meta.to_string(),
char_bag: meta.name.as_ref().into(),
string: meta.name.to_string(),
})
.collect::<Vec<_>>();

View file

@ -1,6 +1,6 @@
use gpui::{AnyView, DefiniteLength};
use crate::prelude::*;
use crate::{prelude::*, IconPosition};
use crate::{
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Icon, IconSize, Label, LineHeightStyle,
};
@ -14,6 +14,7 @@ pub struct Button {
label_color: Option<Color>,
selected_label: Option<SharedString>,
icon: Option<Icon>,
icon_position: Option<IconPosition>,
icon_size: Option<IconSize>,
icon_color: Option<Color>,
selected_icon: Option<Icon>,
@ -27,6 +28,7 @@ impl Button {
label_color: None,
selected_label: None,
icon: None,
icon_position: None,
icon_size: None,
icon_color: None,
selected_icon: None,
@ -48,6 +50,11 @@ impl Button {
self
}
pub fn icon_position(mut self, icon_position: impl Into<Option<IconPosition>>) -> Self {
self.icon_position = icon_position.into();
self
}
pub fn icon_size(mut self, icon_size: impl Into<Option<IconSize>>) -> Self {
self.icon_size = icon_size.into();
self
@ -141,19 +148,29 @@ impl RenderOnce for Button {
self.label_color.unwrap_or_default()
};
self.base
.children(self.icon.map(|icon| {
ButtonIcon::new(icon)
.disabled(is_disabled)
.selected(is_selected)
.selected_icon(self.selected_icon)
.size(self.icon_size)
.color(self.icon_color)
}))
.child(
Label::new(label)
.color(label_color)
.line_height_style(LineHeightStyle::UILabel),
)
self.base.child(
h_stack()
.gap_1()
.map(|this| {
if self.icon_position == Some(IconPosition::End) {
this.flex_row_reverse()
} else {
this
}
})
.child(
Label::new(label)
.color(label_color)
.line_height_style(LineHeightStyle::UILabel),
)
.children(self.icon.map(|icon| {
ButtonIcon::new(icon)
.disabled(is_disabled)
.selected(is_selected)
.selected_icon(self.selected_icon)
.size(self.icon_size)
.color(self.icon_color)
})),
)
}
}

View file

@ -30,6 +30,13 @@ pub trait ButtonCommon: Clickable + Disableable {
fn tooltip(self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self;
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
pub enum IconPosition {
#[default]
Start,
End,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
pub enum ButtonStyle {
/// A filled button with a solid background color. Provides emphasis versus
@ -347,6 +354,7 @@ impl RenderOnce for ButtonLike {
ButtonSize::None => this,
})
.bg(self.style.enabled(cx).background)
.when(self.disabled, |this| this.cursor_not_allowed())
.when(!self.disabled, |this| {
this.cursor_pointer()
.hover(|hover| hover.bg(self.style.hovered(cx).background))

View file

@ -239,7 +239,6 @@ impl Render for ContextMenu {
action,
} => {
let handler = handler.clone();
let dismiss = cx.listener(|_, _, cx| cx.emit(DismissEvent));
let label_element = if let Some(icon) = icon {
h_stack()
@ -263,10 +262,7 @@ impl Render for ContextMenu {
})),
)
.selected(Some(ix) == self.selected_index)
.on_click(move |event, cx| {
handler(cx);
dismiss(event, cx)
})
.on_click(move |_, cx| handler(cx))
.into_any_element()
}
},

View file

@ -51,6 +51,7 @@ pub enum Icon {
CopilotDisabled,
Dash,
Envelope,
ExternalLink,
ExclamationTriangle,
Exit,
File,
@ -123,13 +124,13 @@ impl Icon {
Icon::Close => "icons/x.svg",
Icon::Collab => "icons/user_group_16.svg",
Icon::Copilot => "icons/copilot.svg",
Icon::CopilotInit => "icons/copilot_init.svg",
Icon::CopilotError => "icons/copilot_error.svg",
Icon::CopilotDisabled => "icons/copilot_disabled.svg",
Icon::Dash => "icons/dash.svg",
Icon::Envelope => "icons/feedback.svg",
Icon::ExclamationTriangle => "icons/warning.svg",
Icon::ExternalLink => "icons/external_link.svg",
Icon::Exit => "icons/exit.svg",
Icon::File => "icons/file.svg",
Icon::FileDoc => "icons/file_icons/book.svg",

View file

@ -4,7 +4,7 @@ use story::Story;
use crate::prelude::*;
use crate::{right_click_menu, ContextMenu, Label};
actions!(PrintCurrentDate, PrintBestFood);
actions!(context_menu, [PrintCurrentDate, PrintBestFood]);
fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<ContextMenu> {
ContextMenu::build(cx, |menu, _| {

View file

@ -1,4 +1,5 @@
use gpui::{actions, Div, Render};
use gpui::NoAction;
use gpui::{Div, Render};
use itertools::Itertools;
use story::Story;
@ -7,8 +8,6 @@ use crate::KeyBinding;
pub struct KeybindingStory;
actions!(NoAction);
pub fn binding(key: &str) -> gpui::KeyBinding {
gpui::KeyBinding::new(key, NoAction {}, None)
}

View file

@ -12,6 +12,6 @@ pub use crate::selectable::*;
pub use crate::{h_stack, v_stack};
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
pub use crate::{ButtonCommon, Color, StyledExt};
pub use crate::{Icon, IconElement, IconSize};
pub use crate::{Icon, IconElement, IconPosition, IconSize};
pub use crate::{Label, LabelCommon, LabelSize, LineHeightStyle};
pub use theme::ActiveTheme;

View file

@ -10,9 +10,9 @@ use settings::{update_settings_file, Settings};
use std::sync::Arc;
use ui::{prelude::*, ListItem};
use util::ResultExt;
use workspace::{ui::HighlightedLabel, Workspace};
use workspace::{ui::HighlightedLabel, ModalView, Workspace};
actions!(ToggleBaseKeymapSelector);
actions!(welcome, [ToggleBaseKeymapSelector]);
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
@ -47,6 +47,7 @@ impl FocusableView for BaseKeymapSelector {
}
impl EventEmitter<DismissEvent> for BaseKeymapSelector {}
impl ModalView for BaseKeymapSelector {}
impl BaseKeymapSelector {
pub fn new(

View file

@ -770,7 +770,7 @@ pub mod test {
pub focus_handle: FocusHandle,
pub size: f32,
}
actions!(ToggleTestPanel);
actions!(test, [ToggleTestPanel]);
impl EventEmitter<PanelEvent> for TestPanel {}

View file

@ -1,11 +1,32 @@
use gpui::{
div, prelude::*, px, AnyView, Div, FocusHandle, ManagedView, Render, Subscription, View,
ViewContext,
div, prelude::*, px, AnyView, Div, FocusHandle, ManagedView, Render, Subscription, Task, View,
ViewContext, WindowContext,
};
use ui::{h_stack, v_stack};
pub trait ModalView: ManagedView {
fn dismiss(&mut self, cx: &mut ViewContext<Self>) -> Task<bool> {
Task::ready(true)
}
}
trait ModalViewHandle {
fn should_dismiss(&mut self, cx: &mut WindowContext) -> Task<bool>;
fn view(&self) -> AnyView;
}
impl<V: ModalView> ModalViewHandle for View<V> {
fn should_dismiss(&mut self, cx: &mut WindowContext) -> Task<bool> {
self.update(cx, |this, cx| this.dismiss(cx))
}
fn view(&self) -> AnyView {
self.clone().into()
}
}
pub struct ActiveModal {
modal: AnyView,
modal: Box<dyn ModalViewHandle>,
subscription: Subscription,
previous_focus_handle: Option<FocusHandle>,
focus_handle: FocusHandle,
@ -22,11 +43,11 @@ impl ModalLayer {
pub fn toggle_modal<V, B>(&mut self, cx: &mut ViewContext<Self>, build_view: B)
where
V: ManagedView,
V: ModalView,
B: FnOnce(&mut ViewContext<V>) -> V,
{
if let Some(active_modal) = &self.active_modal {
let is_close = active_modal.modal.clone().downcast::<V>().is_ok();
let is_close = active_modal.modal.view().downcast::<V>().is_ok();
self.hide_modal(cx);
if is_close {
return;
@ -38,10 +59,10 @@ impl ModalLayer {
pub fn show_modal<V>(&mut self, new_modal: View<V>, cx: &mut ViewContext<Self>)
where
V: ManagedView,
V: ModalView,
{
self.active_modal = Some(ActiveModal {
modal: new_modal.clone().into(),
modal: Box::new(new_modal.clone()),
subscription: cx.subscribe(&new_modal, |this, modal, e, cx| this.hide_modal(cx)),
previous_focus_handle: cx.focused(),
focus_handle: cx.focus_handle(),
@ -51,15 +72,28 @@ impl ModalLayer {
}
pub fn hide_modal(&mut self, cx: &mut ViewContext<Self>) {
if let Some(active_modal) = self.active_modal.take() {
if let Some(previous_focus) = active_modal.previous_focus_handle {
if active_modal.focus_handle.contains_focused(cx) {
previous_focus.focus(cx);
}
}
}
let Some(active_modal) = self.active_modal.as_mut() else {
return;
};
cx.notify();
let dismiss = active_modal.modal.should_dismiss(cx);
cx.spawn(|this, mut cx| async move {
if dismiss.await {
this.update(&mut cx, |this, cx| {
if let Some(active_modal) = this.active_modal.take() {
if let Some(previous_focus) = active_modal.previous_focus_handle {
if active_modal.focus_handle.contains_focused(cx) {
previous_focus.focus(cx);
}
}
cx.notify();
}
})
.ok();
}
})
.detach();
}
pub fn active_modal<V>(&self) -> Option<View<V>>
@ -67,7 +101,7 @@ impl ModalLayer {
V: 'static,
{
let active_modal = self.active_modal.as_ref()?;
active_modal.modal.clone().downcast::<V>().ok()
active_modal.modal.view().downcast::<V>().ok()
}
}
@ -98,7 +132,7 @@ impl Render for ModalLayer {
.on_mouse_down_out(cx.listener(|this, _, cx| {
this.hide_modal(cx);
}))
.child(active_modal.modal.clone()),
.child(active_modal.modal.view()),
),
)
}

Some files were not shown because too many files have changed in this diff Show more