Merge remote-tracking branch 'origin/main' into fabric-themes

This commit is contained in:
Nathan Sobo 2024-01-02 09:57:51 -07:00
commit dc6e09a7c4
180 changed files with 976 additions and 1180 deletions

View file

@ -2,8 +2,8 @@ use auto_update::{AutoUpdateStatus, AutoUpdater, DismissErrorMessage};
use editor::Editor;
use futures::StreamExt;
use gpui::{
actions, svg, AppContext, CursorStyle, Div, EventEmitter, InteractiveElement as _, Model,
ParentElement as _, Render, SharedString, Stateful, StatefulInteractiveElement, Styled, View,
actions, svg, AppContext, CursorStyle, EventEmitter, InteractiveElement as _, Model,
ParentElement as _, Render, SharedString, StatefulInteractiveElement, Styled, View,
ViewContext, VisualContext as _,
};
use language::{LanguageRegistry, LanguageServerBinaryStatus};
@ -55,7 +55,7 @@ impl ActivityIndicator {
) -> View<ActivityIndicator> {
let project = workspace.project().clone();
let auto_updater = AutoUpdater::get(cx);
let this = cx.build_view(|cx: &mut ViewContext<Self>| {
let this = cx.new_view(|cx: &mut ViewContext<Self>| {
let mut status_events = languages.language_server_binary_statuses();
cx.spawn(|this, mut cx| async move {
while let Some((language, event)) = status_events.next().await {
@ -101,9 +101,9 @@ impl ActivityIndicator {
);
});
workspace.add_item(
Box::new(cx.build_view(|cx| {
Editor::for_buffer(buffer, Some(project.clone()), cx)
})),
Box::new(
cx.new_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx)),
),
cx,
);
}
@ -304,9 +304,7 @@ impl ActivityIndicator {
impl EventEmitter<Event> for ActivityIndicator {}
impl Render for ActivityIndicator {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let content = self.content_to_render(cx);
let mut result = h_stack()

View file

@ -30,9 +30,9 @@ use fs::Fs;
use futures::StreamExt;
use gpui::{
canvas, div, point, relative, rems, uniform_list, Action, AnyElement, AppContext,
AsyncWindowContext, AvailableSpace, ClipboardItem, Context, Div, EventEmitter, FocusHandle,
Focusable, FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement,
IntoElement, Model, ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString,
AsyncWindowContext, AvailableSpace, ClipboardItem, Context, EventEmitter, FocusHandle,
FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, IntoElement, Model,
ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString,
StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle,
View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
};
@ -126,7 +126,7 @@ impl AssistantPanel {
// TODO: deserialize state.
let workspace_handle = workspace.clone();
workspace.update(&mut cx, |workspace, cx| {
cx.build_view::<Self>(|cx| {
cx.new_view::<Self>(|cx| {
const CONVERSATION_WATCH_DURATION: Duration = Duration::from_millis(100);
let _watch_saved_conversations = cx.spawn(move |this, mut cx| async move {
let mut events = fs
@ -147,10 +147,10 @@ impl AssistantPanel {
anyhow::Ok(())
});
let toolbar = cx.build_view(|cx| {
let toolbar = cx.new_view(|cx| {
let mut toolbar = Toolbar::new();
toolbar.set_can_navigate(false, cx);
toolbar.add_item(cx.build_view(|cx| BufferSearchBar::new(cx)), cx);
toolbar.add_item(cx.new_view(|cx| BufferSearchBar::new(cx)), cx);
toolbar
});
@ -306,7 +306,7 @@ impl AssistantPanel {
// Retrieve Credentials Authenticates the Provider
provider.retrieve_credentials(cx);
let codegen = cx.build_model(|cx| {
let codegen = cx.new_model(|cx| {
Codegen::new(editor.read(cx).buffer().clone(), codegen_kind, provider, cx)
});
@ -332,7 +332,7 @@ impl AssistantPanel {
}
let measurements = Rc::new(Cell::new(BlockMeasurements::default()));
let inline_assistant = cx.build_view(|cx| {
let inline_assistant = cx.new_view(|cx| {
InlineAssistant::new(
inline_assist_id,
measurements.clone(),
@ -790,7 +790,7 @@ impl AssistantPanel {
}
fn new_conversation(&mut self, cx: &mut ViewContext<Self>) -> View<ConversationEditor> {
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
ConversationEditor::new(
self.completion_provider.clone(),
self.languages.clone(),
@ -1058,7 +1058,7 @@ impl AssistantPanel {
cx.spawn(|this, mut cx| async move {
let saved_conversation = fs.load(&path).await?;
let saved_conversation = serde_json::from_str(&saved_conversation)?;
let conversation = cx.build_model(|cx| {
let conversation = cx.new_model(|cx| {
Conversation::deserialize(saved_conversation, path.clone(), languages, cx)
})?;
this.update(&mut cx, |this, cx| {
@ -1067,7 +1067,7 @@ impl AssistantPanel {
if let Some(ix) = this.editor_index_for_path(&path, cx) {
this.set_active_editor_index(Some(ix), cx);
} else {
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
ConversationEditor::for_conversation(conversation, fs, workspace, cx)
});
this.add_conversation(editor, cx);
@ -1093,7 +1093,7 @@ impl AssistantPanel {
}
fn build_api_key_editor(cx: &mut ViewContext<AssistantPanel>) -> View<Editor> {
cx.build_view(|cx| {
cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("sk-000000000000000000000000000000000000000000000000", cx);
editor
@ -1101,9 +1101,7 @@ fn build_api_key_editor(cx: &mut ViewContext<AssistantPanel>) -> View<Editor> {
}
impl Render for AssistantPanel {
type Element = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
if let Some(api_key_editor) = self.api_key_editor.clone() {
v_stack()
.on_action(cx.listener(AssistantPanel::save_credentials))
@ -1337,7 +1335,7 @@ impl Conversation {
completion_provider: Arc<dyn CompletionProvider>,
) -> Self {
let markdown = language_registry.language_for_name("Markdown");
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "");
buffer.set_language_registry(language_registry);
cx.spawn(|buffer, mut cx| async move {
@ -1432,7 +1430,7 @@ impl Conversation {
let markdown = language_registry.language_for_name("Markdown");
let mut message_anchors = Vec::new();
let mut next_message_id = MessageId(0);
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), saved_conversation.text);
for message in saved_conversation.messages {
message_anchors.push(MessageAnchor {
@ -2083,7 +2081,7 @@ impl ConversationEditor {
cx: &mut ViewContext<Self>,
) -> Self {
let conversation =
cx.build_model(|cx| Conversation::new(language_registry, cx, completion_provider));
cx.new_model(|cx| Conversation::new(language_registry, cx, completion_provider));
Self::for_conversation(conversation, fs, workspace, cx)
}
@ -2093,7 +2091,7 @@ impl ConversationEditor {
workspace: WeakView<Workspace>,
cx: &mut ViewContext<Self>,
) -> Self {
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
let mut editor = Editor::for_buffer(conversation.read(cx).buffer.clone(), None, cx);
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
editor.set_show_gutter(false, cx);
@ -2513,9 +2511,7 @@ impl ConversationEditor {
impl EventEmitter<ConversationEditorEvent> for ConversationEditor {}
impl Render for ConversationEditor {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
div()
.key_context("ConversationEditor")
.capture_action(cx.listener(ConversationEditor::cancel_last_assist))
@ -2618,9 +2614,7 @@ struct InlineAssistant {
impl EventEmitter<InlineAssistantEvent> for InlineAssistant {}
impl Render for InlineAssistant {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let measurements = self.measurements.get();
h_stack()
.w_full()
@ -2714,7 +2708,7 @@ impl InlineAssistant {
semantic_index: Option<Model<SemanticIndex>>,
project: Model<Project>,
) -> Self {
let prompt_editor = cx.build_view(|cx| {
let prompt_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
let placeholder = match codegen.read(cx).kind() {
CodegenKind::Transform { .. } => "Enter transformation prompt…",
@ -3135,8 +3129,7 @@ mod tests {
let registry = Arc::new(LanguageRegistry::test());
let completion_provider = Arc::new(FakeCompletionProvider::new());
let conversation =
cx.build_model(|cx| Conversation::new(registry, cx, completion_provider));
let conversation = cx.new_model(|cx| Conversation::new(registry, cx, completion_provider));
let buffer = conversation.read(cx).buffer.clone();
let message_1 = conversation.read(cx).message_anchors[0].clone();
@ -3267,8 +3260,7 @@ mod tests {
let registry = Arc::new(LanguageRegistry::test());
let completion_provider = Arc::new(FakeCompletionProvider::new());
let conversation =
cx.build_model(|cx| Conversation::new(registry, cx, completion_provider));
let conversation = cx.new_model(|cx| Conversation::new(registry, cx, completion_provider));
let buffer = conversation.read(cx).buffer.clone();
let message_1 = conversation.read(cx).message_anchors[0].clone();
@ -3366,8 +3358,7 @@ mod tests {
init(cx);
let registry = Arc::new(LanguageRegistry::test());
let completion_provider = Arc::new(FakeCompletionProvider::new());
let conversation =
cx.build_model(|cx| Conversation::new(registry, cx, completion_provider));
let conversation = cx.new_model(|cx| Conversation::new(registry, cx, completion_provider));
let buffer = conversation.read(cx).buffer.clone();
let message_1 = conversation.read(cx).message_anchors[0].clone();
@ -3452,7 +3443,7 @@ mod tests {
let registry = Arc::new(LanguageRegistry::test());
let completion_provider = Arc::new(FakeCompletionProvider::new());
let conversation =
cx.build_model(|cx| Conversation::new(registry.clone(), cx, completion_provider));
cx.new_model(|cx| Conversation::new(registry.clone(), cx, completion_provider));
let buffer = conversation.read(cx).buffer.clone();
let message_0 = conversation.read(cx).message_anchors[0].id;
let message_1 = conversation.update(cx, |conversation, cx| {
@ -3485,7 +3476,7 @@ mod tests {
]
);
let deserialized_conversation = cx.build_model(|cx| {
let deserialized_conversation = cx.new_model(|cx| {
Conversation::deserialize(
conversation.read(cx).serialize(cx),
Default::default(),

View file

@ -395,14 +395,14 @@ mod tests {
}
"};
let buffer =
cx.build_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 0))..snapshot.anchor_after(Point::new(4, 5))
});
let provider = Arc::new(FakeCompletionProvider::new());
let codegen = cx.build_model(|cx| {
let codegen = cx.new_model(|cx| {
Codegen::new(
buffer.clone(),
CodegenKind::Transform { range },
@ -461,14 +461,14 @@ mod tests {
}
"};
let buffer =
cx.build_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let position = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 6))
});
let provider = Arc::new(FakeCompletionProvider::new());
let codegen = cx.build_model(|cx| {
let codegen = cx.new_model(|cx| {
Codegen::new(
buffer.clone(),
CodegenKind::Generate { position },
@ -526,14 +526,14 @@ mod tests {
"}\n" //
);
let buffer =
cx.build_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let position = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 2))
});
let provider = Arc::new(FakeCompletionProvider::new());
let codegen = cx.build_model(|cx| {
let codegen = cx.new_model(|cx| {
Codegen::new(
buffer.clone(),
CodegenKind::Generate { position },

View file

@ -254,7 +254,7 @@ pub(crate) mod tests {
}
"};
let buffer =
cx.build_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
let snapshot = buffer.read(cx).snapshot();
assert_eq!(

View file

@ -94,7 +94,7 @@ pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppCo
.detach();
if let Some(version) = ZED_APP_VERSION.or_else(|| cx.app_metadata().app_version) {
let auto_updater = cx.build_model(|cx| {
let auto_updater = cx.new_model(|cx| {
let updater = AutoUpdater::new(version, http_client, server_url);
let mut update_subscription = AutoUpdateSetting::get_global(cx)
@ -160,7 +160,7 @@ pub fn notify_of_any_new_update(cx: &mut ViewContext<Workspace>) -> Option<()> {
if should_show_notification {
workspace.update(&mut cx, |workspace, cx| {
workspace.show_notification(0, cx, |cx| {
cx.build_view(|_| UpdateNotification::new(version))
cx.new_view(|_| UpdateNotification::new(version))
});
updater
.read(cx)

View file

@ -1,5 +1,5 @@
use gpui::{
div, DismissEvent, Div, EventEmitter, InteractiveElement, ParentElement, Render,
div, DismissEvent, Element, EventEmitter, InteractiveElement, ParentElement, Render,
SemanticVersion, StatefulInteractiveElement, Styled, ViewContext,
};
use menu::Cancel;
@ -13,9 +13,7 @@ pub struct UpdateNotification {
impl EventEmitter<DismissEvent> for UpdateNotification {}
impl Render for UpdateNotification {
type Element = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
let app_name = cx.global::<ReleaseChannel>().display_name();
v_stack()

View file

@ -1,6 +1,6 @@
use editor::Editor;
use gpui::{
Div, Element, EventEmitter, IntoElement, ParentElement, Render, StyledText, Subscription,
Element, EventEmitter, IntoElement, ParentElement, Render, StyledText, Subscription,
ViewContext,
};
use itertools::Itertools;
@ -30,9 +30,7 @@ impl Breadcrumbs {
impl EventEmitter<ToolbarItemEvent> for Breadcrumbs {}
impl Render for Breadcrumbs {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let element = h_stack().text_ui();
let Some(active_item) = self.active_item.as_ref() else {
return element;
@ -88,8 +86,13 @@ impl ToolbarItemView for Breadcrumbs {
cx,
Box::new(move |event, cx| {
if let ItemEvent::UpdateBreadcrumbs = event {
this.update(cx, |_, cx| {
this.update(cx, |this, cx| {
cx.notify();
if let Some(active_item) = this.active_item.as_ref() {
cx.emit(ToolbarItemEvent::ChangeLocation(
active_item.breadcrumb_location(cx),
))
}
})
.ok();
}

View file

@ -24,7 +24,7 @@ pub use room::Room;
pub fn init(client: Arc<Client>, user_store: Model<UserStore>, cx: &mut AppContext) {
CallSettings::register(cx);
let active_call = cx.build_model(|cx| ActiveCall::new(client, user_store, cx));
let active_call = cx.new_model(|cx| ActiveCall::new(client, user_store, cx));
cx.set_global(active_call);
}

View file

@ -246,7 +246,7 @@ impl Room {
cx.spawn(move |mut cx| async move {
let response = client.request(proto::CreateRoom {}).await?;
let room_proto = response.room.ok_or_else(|| anyhow!("invalid room"))?;
let room = cx.build_model(|cx| {
let room = cx.new_model(|cx| {
Self::new(
room_proto.id,
None,
@ -343,7 +343,7 @@ impl Room {
mut cx: AsyncAppContext,
) -> Result<Model<Self>> {
let room_proto = response.room.ok_or_else(|| anyhow!("invalid room"))?;
let room = cx.build_model(|cx| {
let room = cx.new_model(|cx| {
Self::new(
room_proto.id,
response.channel_id,

View file

@ -61,14 +61,14 @@ impl ChannelBuffer {
.map(language::proto::deserialize_operation)
.collect::<Result<Vec<_>, _>>()?;
let buffer = cx.build_model(|_| {
let buffer = cx.new_model(|_| {
language::Buffer::remote(response.buffer_id, response.replica_id as u16, base_text)
})?;
buffer.update(&mut cx, |buffer, cx| buffer.apply_ops(operations, cx))??;
let subscription = client.subscribe_to_entity(channel.id)?;
anyhow::Ok(cx.build_model(|cx| {
anyhow::Ok(cx.new_model(|cx| {
cx.subscribe(&buffer, Self::on_buffer_update).detach();
cx.on_release(Self::release).detach();
let mut this = Self {

View file

@ -99,7 +99,7 @@ impl ChannelChat {
let messages = messages_from_proto(response.messages, &user_store, &mut cx).await?;
let loaded_all_messages = response.done;
Ok(cx.build_model(|cx| {
Ok(cx.new_model(|cx| {
cx.on_release(Self::release).detach();
let mut this = Self {
channel_id: channel.id,

View file

@ -20,7 +20,7 @@ use util::{async_maybe, ResultExt};
pub fn init(client: &Arc<Client>, user_store: Model<UserStore>, cx: &mut AppContext) {
let channel_store =
cx.build_model(|cx| ChannelStore::new(client.clone(), user_store.clone(), cx));
cx.new_model(|cx| ChannelStore::new(client.clone(), user_store.clone(), cx));
cx.set_global(channel_store);
}

View file

@ -345,7 +345,7 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
fn init_test(cx: &mut AppContext) -> Model<ChannelStore> {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);

View file

@ -1579,15 +1579,15 @@ mod tests {
async { Ok(()) }
},
);
let model1 = cx.build_model(|_| TestModel {
let model1 = cx.new_model(|_| TestModel {
id: 1,
subscription: None,
});
let model2 = cx.build_model(|_| TestModel {
let model2 = cx.new_model(|_| TestModel {
id: 2,
subscription: None,
});
let model3 = cx.build_model(|_| TestModel {
let model3 = cx.new_model(|_| TestModel {
id: 3,
subscription: None,
});
@ -1620,7 +1620,7 @@ mod tests {
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
let model = cx.build_model(|_| TestModel::default());
let model = cx.new_model(|_| TestModel::default());
let (done_tx1, _done_rx1) = smol::channel::unbounded();
let (done_tx2, mut done_rx2) = smol::channel::unbounded();
let subscription1 = client.add_message_handler(
@ -1648,7 +1648,7 @@ mod tests {
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
let model = cx.build_model(|_| TestModel::default());
let model = cx.new_model(|_| TestModel::default());
let (done_tx, mut done_rx) = smol::channel::unbounded();
let subscription = client.add_message_handler(
model.clone().downgrade(),

View file

@ -194,7 +194,7 @@ impl FakeServer {
client: Arc<Client>,
cx: &mut TestAppContext,
) -> Model<UserStore> {
let user_store = cx.build_model(|cx| UserStore::new(client, cx));
let user_store = cx.new_model(|cx| UserStore::new(client, cx));
assert_eq!(
self.receive::<proto::GetUsers>()
.await

View file

@ -209,8 +209,8 @@ impl TestServer {
});
let fs = FakeFs::new(cx.executor());
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.new_model(|cx| WorkspaceStore::new(client.clone(), cx));
let mut language_registry = LanguageRegistry::test();
language_registry.set_executor(cx.executor());
let app_state = Arc::new(workspace::AppState {
@ -260,8 +260,6 @@ impl TestServer {
.store(true, SeqCst);
}
//todo!(workspace)
#[allow(dead_code)]
pub fn simulate_long_connection_interruption(
&self,
peer_id: PeerId,

View file

@ -105,7 +105,7 @@ impl ChannelView {
}
}
let view = cx.build_view(|cx| {
let view = cx.new_view(|cx| {
let mut this = Self::new(project, channel_store, channel_buffer, cx);
this.acknowledge_buffer_version(cx);
this
@ -133,7 +133,7 @@ impl ChannelView {
cx: &mut ViewContext<Self>,
) -> Self {
let buffer = channel_buffer.read(cx).buffer();
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
let mut editor = Editor::for_buffer(buffer, None, cx);
editor.set_collaboration_hub(Box::new(ChannelBufferCollaborationHub(
channel_buffer.clone(),
@ -222,10 +222,8 @@ impl ChannelView {
impl EventEmitter<EditorEvent> for ChannelView {}
impl Render for ChannelView {
type Element = AnyView;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
self.editor.clone().into()
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
self.editor.clone()
}
}
@ -276,7 +274,7 @@ impl Item for ChannelView {
}
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<View<Self>> {
Some(cx.build_view(|cx| {
Some(cx.new_view(|cx| {
Self::new(
self.project.clone(),
self.channel_store.clone(),

View file

@ -8,8 +8,8 @@ use db::kvp::KEY_VALUE_STORE;
use editor::Editor;
use gpui::{
actions, div, list, prelude::*, px, serde_json, AnyElement, AppContext, AsyncWindowContext,
ClickEvent, Div, ElementId, EventEmitter, FocusableView, ListOffset, ListScrollEvent,
ListState, Model, Render, Subscription, Task, View, ViewContext, VisualContext, WeakView,
ClickEvent, ElementId, EventEmitter, FocusableView, ListOffset, ListScrollEvent, ListState,
Model, Render, Subscription, Task, View, ViewContext, VisualContext, WeakView,
};
use language::LanguageRegistry;
use menu::Confirm;
@ -81,18 +81,18 @@ impl ChatPanel {
let channel_store = ChannelStore::global(cx);
let languages = workspace.app_state().languages.clone();
let input_editor = cx.build_view(|cx| {
let input_editor = cx.new_view(|cx| {
MessageEditor::new(
languages.clone(),
channel_store.clone(),
cx.build_view(|cx| Editor::auto_height(4, cx)),
cx.new_view(|cx| Editor::auto_height(4, cx)),
cx,
)
});
let workspace_handle = workspace.weak_handle();
cx.build_view(|cx: &mut ViewContext<Self>| {
cx.new_view(|cx: &mut ViewContext<Self>| {
let view = cx.view().downgrade();
let message_list =
ListState::new(0, gpui::ListAlignment::Bottom, px(1000.), move |ix, cx| {
@ -549,9 +549,7 @@ impl ChatPanel {
impl EventEmitter<Event> for ChatPanel {}
impl Render for ChatPanel {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
div()
.full()
.child(if self.client.user_id().is_some() {

View file

@ -3,7 +3,7 @@ use client::UserId;
use collections::HashMap;
use editor::{AnchorRangeExt, Editor};
use gpui::{
AnyView, AsyncWindowContext, FocusableView, Model, Render, SharedString, Task, View,
AsyncWindowContext, Element, FocusableView, Model, Render, SharedString, Task, View,
ViewContext, WeakView,
};
use language::{language_settings::SoftWrap, Buffer, BufferSnapshot, LanguageRegistry};
@ -196,9 +196,7 @@ impl MessageEditor {
}
impl Render for MessageEditor {
type Element = AnyView;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
self.editor.to_any()
}
}
@ -221,7 +219,7 @@ mod tests {
MessageEditor::new(
language_registry,
ChannelStore::global(cx),
cx.build_view(|cx| Editor::auto_height(4, cx)),
cx.new_view(|cx| Editor::auto_height(4, cx)),
cx,
)
});
@ -275,7 +273,7 @@ mod tests {
cx.update(|cx| {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let settings = SettingsStore::test(cx);
cx.set_global(settings);
theme::init(theme::LoadThemes::JustBase, cx);

View file

@ -17,9 +17,9 @@ use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
actions, canvas, div, fill, list, overlay, point, prelude::*, px, serde_json, AnyElement,
AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter,
FocusHandle, Focusable, FocusableView, InteractiveElement, IntoElement, ListOffset, ListState,
Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce,
SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
FocusHandle, FocusableView, InteractiveElement, IntoElement, ListOffset, ListState, Model,
MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Render, RenderOnce, SharedString,
Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
};
use menu::{Cancel, Confirm, SelectNext, SelectPrev};
use project::{Fs, Project};
@ -177,8 +177,8 @@ enum ListEntry {
impl CollabPanel {
pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
cx.build_view(|cx| {
let filter_editor = cx.build_view(|cx| {
cx.new_view(|cx| {
let filter_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Filter...", cx);
editor
@ -201,7 +201,7 @@ impl CollabPanel {
})
.detach();
let channel_name_editor = cx.build_view(|cx| Editor::single_line(cx));
let channel_name_editor = cx.new_view(|cx| Editor::single_line(cx));
cx.subscribe(&channel_name_editor, |this: &mut Self, _, event, cx| {
if let editor::EditorEvent::Blurred = event {
@ -2118,7 +2118,7 @@ impl CollabPanel {
.flex()
.w_full()
.on_drag(channel.clone(), move |channel, cx| {
cx.build_view(|_| DraggedChannelView {
cx.new_view(|_| DraggedChannelView {
channel: channel.clone(),
width,
})
@ -2263,9 +2263,7 @@ fn render_tree_branch(is_last: bool, cx: &mut WindowContext) -> impl IntoElement
}
impl Render for CollabPanel {
type Element = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
v_stack()
.key_context("CollabPanel")
.on_action(cx.listener(CollabPanel::cancel))
@ -2453,9 +2451,7 @@ struct DraggedChannelView {
}
impl Render for DraggedChannelView {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
h_stack()
.font(ui_font)

View file

@ -5,9 +5,9 @@ use client::{
};
use fuzzy::{match_strings, StringMatchCandidate};
use gpui::{
actions, div, overlay, AppContext, ClipboardItem, DismissEvent, Div, EventEmitter,
FocusableView, Model, ParentElement, Render, Styled, Subscription, Task, View, ViewContext,
VisualContext, WeakView,
actions, div, overlay, AppContext, ClipboardItem, DismissEvent, EventEmitter, FocusableView,
Model, ParentElement, Render, Styled, Subscription, Task, View, ViewContext, VisualContext,
WeakView,
};
use picker::{Picker, PickerDelegate};
use std::sync::Arc;
@ -42,7 +42,7 @@ impl ChannelModal {
) -> Self {
cx.observe(&channel_store, |_, _, cx| cx.notify()).detach();
let channel_modal = cx.view().downgrade();
let picker = cx.build_view(|cx| {
let picker = cx.new_view(|cx| {
Picker::new(
ChannelModalDelegate {
channel_modal,
@ -142,9 +142,7 @@ impl FocusableView for ChannelModal {
}
impl Render for ChannelModal {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let channel_store = self.channel_store.read(cx);
let Some(channel) = channel_store.channel_for_id(self.channel_id) else {
return div();

View file

@ -1,7 +1,7 @@
use client::{ContactRequestStatus, User, UserStore};
use gpui::{
AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Model,
ParentElement as _, Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model, ParentElement as _,
Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
};
use picker::{Picker, PickerDelegate};
use std::sync::Arc;
@ -22,7 +22,7 @@ impl ContactFinder {
potential_contacts: Arc::from([]),
selected_index: 0,
};
let picker = cx.build_view(|cx| Picker::new(delegate, cx).modal(false));
let picker = cx.new_view(|cx| Picker::new(delegate, cx).modal(false));
Self { picker }
}
@ -35,7 +35,7 @@ impl ContactFinder {
}
impl Render for ContactFinder {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
v_stack()
.elevation_3(cx)
.child(
@ -51,8 +51,6 @@ impl Render for ContactFinder {
.child(self.picker.clone())
.w(rems(34.))
}
type Element = Div;
}
pub struct ContactFinderDelegate {

View file

@ -3,8 +3,8 @@ use auto_update::AutoUpdateStatus;
use call::{ActiveCall, ParticipantLocation, Room};
use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore};
use gpui::{
actions, canvas, div, point, px, rems, Action, AnyElement, AppContext, Div, Element, Hsla,
InteractiveElement, IntoElement, Model, ParentElement, Path, Render, Stateful,
actions, canvas, div, point, px, rems, Action, AnyElement, AppContext, Element, Hsla,
InteractiveElement, IntoElement, Model, ParentElement, Path, Render,
StatefulInteractiveElement, Styled, Subscription, View, ViewContext, VisualContext, WeakView,
WindowBounds,
};
@ -36,7 +36,7 @@ actions!(
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(|workspace: &mut Workspace, cx| {
let titlebar_item = cx.build_view(|cx| CollabTitlebarItem::new(workspace, cx));
let titlebar_item = cx.new_view(|cx| CollabTitlebarItem::new(workspace, cx));
workspace.set_titlebar_item(titlebar_item.into(), cx)
})
.detach();
@ -56,9 +56,7 @@ pub struct CollabTitlebarItem {
}
impl Render for CollabTitlebarItem {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let room = ActiveCall::global(cx).read(cx).room().cloned();
let current_user = self.user_store.read(cx).current_user();
let client = self.client.clone();

View file

@ -7,9 +7,9 @@ pub struct FacePile {
}
impl RenderOnce for FacePile {
type Rendered = Div;
type Output = Div;
fn render(self, _: &mut WindowContext) -> Self::Rendered {
fn render(self, _: &mut WindowContext) -> Self::Output {
let player_count = self.faces.len();
let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| {
let isnt_last = ix < player_count - 1;

View file

@ -7,9 +7,9 @@ use db::kvp::KEY_VALUE_STORE;
use futures::StreamExt;
use gpui::{
actions, div, img, list, px, serde_json, AnyElement, AppContext, AsyncWindowContext,
CursorStyle, DismissEvent, Div, Element, EventEmitter, FocusHandle, FocusableView,
CursorStyle, DismissEvent, Element, EventEmitter, FocusHandle, FocusableView,
InteractiveElement, IntoElement, ListAlignment, ListScrollEvent, ListState, Model,
ParentElement, Render, Stateful, StatefulInteractiveElement, Styled, Task, View, ViewContext,
ParentElement, Render, StatefulInteractiveElement, Styled, Task, View, ViewContext,
VisualContext, WeakView, WindowContext,
};
use notifications::{NotificationEntry, NotificationEvent, NotificationStore};
@ -87,7 +87,7 @@ impl NotificationPanel {
let user_store = workspace.app_state().user_store.clone();
let workspace_handle = workspace.weak_handle();
cx.build_view(|cx: &mut ViewContext<Self>| {
cx.new_view(|cx: &mut ViewContext<Self>| {
let mut status = client.status();
cx.spawn(|this, mut cx| async move {
while let Some(_) = status.next().await {
@ -503,7 +503,7 @@ impl NotificationPanel {
workspace.dismiss_notification::<NotificationToast>(0, cx);
workspace.show_notification(0, cx, |cx| {
let workspace = cx.view().downgrade();
cx.build_view(|_| NotificationToast {
cx.new_view(|_| NotificationToast {
notification_id,
actor,
text,
@ -540,9 +540,7 @@ impl NotificationPanel {
}
impl Render for NotificationPanel {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Div {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
v_stack()
.size_full()
.child(
@ -706,9 +704,7 @@ impl NotificationToast {
}
impl Render for NotificationToast {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let user = self.actor.clone();
h_stack()

View file

@ -2,7 +2,7 @@ use crate::notification_window_options;
use call::{ActiveCall, IncomingCall};
use futures::StreamExt;
use gpui::{
img, px, AppContext, Div, ParentElement, Render, RenderOnce, Styled, ViewContext,
img, px, AppContext, ParentElement, Render, RenderOnce, Styled, ViewContext,
VisualContext as _, WindowHandle,
};
use settings::Settings;
@ -39,7 +39,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
let options = notification_window_options(screen, window_size);
let window = cx
.open_window(options, |cx| {
cx.build_view(|_| {
cx.new_view(|_| {
IncomingCallNotification::new(
incoming_call.clone(),
app_state.clone(),
@ -117,9 +117,7 @@ impl IncomingCallNotification {
}
impl Render for IncomingCallNotification {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
// TODO: Is there a better place for us to initialize the font?
let (ui_font, ui_font_size) = {
let theme_settings = ThemeSettings::get_global(cx);

View file

@ -2,9 +2,7 @@ use crate::notification_window_options;
use call::{room, ActiveCall};
use client::User;
use collections::HashMap;
use gpui::{
img, px, AppContext, Div, ParentElement, Render, Size, Styled, ViewContext, VisualContext,
};
use gpui::{img, px, AppContext, ParentElement, Render, Size, Styled, ViewContext, VisualContext};
use settings::Settings;
use std::sync::{Arc, Weak};
use theme::ThemeSettings;
@ -29,7 +27,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
for screen in cx.displays() {
let options = notification_window_options(screen, window_size);
let window = cx.open_window(options, |cx| {
cx.build_view(|_| {
cx.new_view(|_| {
ProjectSharedNotification::new(
owner.clone(),
*project_id,
@ -120,9 +118,7 @@ impl ProjectSharedNotification {
}
impl Render for ProjectSharedNotification {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
// TODO: Is there a better place for us to initialize the font?
let (ui_font, ui_font_size) = {
let theme_settings = ThemeSettings::get_global(cx);

View file

@ -6,7 +6,7 @@ use std::{
use collections::{CommandPaletteFilter, HashMap};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
actions, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
actions, Action, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
};
use picker::{Picker, PickerDelegate};
@ -69,7 +69,7 @@ impl CommandPalette {
let delegate =
CommandPaletteDelegate::new(cx.view().downgrade(), commands, previous_focus_handle);
let picker = cx.build_view(|cx| Picker::new(delegate, cx));
let picker = cx.new_view(|cx| Picker::new(delegate, cx));
Self { picker }
}
}
@ -83,9 +83,7 @@ impl FocusableView for CommandPalette {
}
impl Render for CommandPalette {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
v_stack().w(rems(34.)).child(self.picker.clone())
}
}
@ -396,7 +394,7 @@ mod tests {
let project = Project::test(app_state.fs.clone(), [], cx).await;
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx));
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_text("abc", cx);
editor

View file

@ -51,7 +51,7 @@ pub fn init(
node_runtime: Arc<dyn NodeRuntime>,
cx: &mut AppContext,
) {
let copilot = cx.build_model({
let copilot = cx.new_model({
let node_runtime = node_runtime.clone();
move |cx| Copilot::start(new_server_id, http, node_runtime, cx)
});
@ -382,7 +382,7 @@ impl Copilot {
LanguageServer::fake("copilot".into(), Default::default(), cx.to_async());
let http = util::http::FakeHttpClient::create(|_| async { unreachable!() });
let node_runtime = FakeNodeRuntime::new();
let this = cx.build_model(|cx| Self {
let this = cx.new_model(|cx| Self {
server_id: LanguageServerId(0),
http: http.clone(),
node_runtime,
@ -563,7 +563,6 @@ impl Copilot {
}
}
#[allow(dead_code)] // todo!()
fn sign_out(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx);
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
@ -1034,7 +1033,7 @@ mod tests {
async fn test_buffer_management(cx: &mut TestAppContext) {
let (copilot, mut lsp) = Copilot::fake(cx);
let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Hello"));
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Hello"));
let buffer_1_uri: lsp::Url = format!("buffer://{}", buffer_1.entity_id().as_u64())
.parse()
.unwrap();
@ -1052,7 +1051,7 @@ mod tests {
}
);
let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Goodbye"));
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Goodbye"));
let buffer_2_uri: lsp::Url = format!("buffer://{}", buffer_2.entity_id().as_u64())
.parse()
.unwrap();
@ -1126,7 +1125,6 @@ mod tests {
.update(cx, |copilot, cx| copilot.sign_out(cx))
.await
.unwrap();
// todo!() po: these notifications now happen in reverse order?
assert_eq!(
lsp.receive_notification::<lsp::notification::DidCloseTextDocument>()
.await,

View file

@ -1,8 +1,8 @@
use crate::{request::PromptUserDeviceFlow, Copilot, Status};
use gpui::{
div, size, AppContext, Bounds, ClipboardItem, Div, Element, GlobalPixels, InteractiveElement,
IntoElement, ParentElement, Point, Render, Stateful, Styled, ViewContext, VisualContext,
WindowBounds, WindowHandle, WindowKind, WindowOptions,
div, size, AppContext, Bounds, ClipboardItem, Element, GlobalPixels, InteractiveElement,
IntoElement, ParentElement, Point, Render, Styled, ViewContext, VisualContext, WindowBounds,
WindowHandle, WindowKind, WindowOptions,
};
use theme::ActiveTheme;
use ui::{prelude::*, Button, Icon, IconElement, Label};
@ -71,7 +71,7 @@ fn create_copilot_auth_window(
display_id: None,
};
let window = cx.open_window(window_options, |cx| {
cx.build_view(|_| CopilotCodeVerification::new(status.clone()))
cx.new_view(|_| CopilotCodeVerification::new(status.clone()))
});
window
}
@ -181,9 +181,7 @@ impl CopilotCodeVerification {
}
impl Render for CopilotCodeVerification {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let prompt = match &self.status {
Status::SigningIn {
prompt: Some(prompt),

View file

@ -3,8 +3,8 @@ use copilot::{Copilot, SignOut, Status};
use editor::{scroll::autoscroll::Autoscroll, Editor};
use fs::Fs;
use gpui::{
div, Action, AnchorCorner, AppContext, AsyncWindowContext, Div, Entity, ParentElement, Render,
Subscription, View, ViewContext, WeakView, WindowContext,
div, Action, AnchorCorner, AppContext, AsyncWindowContext, Element, Entity, ParentElement,
Render, Subscription, View, ViewContext, WeakView, WindowContext,
};
use language::{
language_settings::{self, all_language_settings, AllLanguageSettings},
@ -34,9 +34,7 @@ pub struct CopilotButton {
}
impl Render for CopilotButton {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let all_language_settings = all_language_settings(None, cx);
if !all_language_settings.copilot.feature_enabled {
return div();

View file

@ -13,10 +13,10 @@ use editor::{
};
use futures::future::try_join_all;
use gpui::{
actions, div, AnyElement, AnyView, AppContext, Context, Div, EventEmitter, FocusHandle,
Focusable, FocusableView, HighlightStyle, InteractiveElement, IntoElement, Model,
ParentElement, Render, SharedString, Styled, StyledText, Subscription, Task, View, ViewContext,
VisualContext, WeakView, WindowContext,
actions, div, AnyElement, AnyView, AppContext, Context, EventEmitter, FocusHandle,
FocusableView, HighlightStyle, InteractiveElement, IntoElement, Model, ParentElement, Render,
SharedString, Styled, StyledText, Subscription, Task, View, ViewContext, VisualContext,
WeakView, WindowContext,
};
use language::{
Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection,
@ -91,9 +91,7 @@ struct DiagnosticGroupState {
impl EventEmitter<EditorEvent> for ProjectDiagnosticsEditor {}
impl Render for ProjectDiagnosticsEditor {
type Element = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let child = if self.path_states.is_empty() {
div()
.bg(cx.theme().colors().editor_background)
@ -153,8 +151,8 @@ impl ProjectDiagnosticsEditor {
let focus_in_subscription =
cx.on_focus_in(&focus_handle, |diagnostics, cx| diagnostics.focus_in(cx));
let excerpts = cx.build_model(|cx| MultiBuffer::new(project_handle.read(cx).replica_id()));
let editor = cx.build_view(|cx| {
let excerpts = cx.new_model(|cx| MultiBuffer::new(project_handle.read(cx).replica_id()));
let editor = cx.new_view(|cx| {
let mut editor =
Editor::for_multibuffer(excerpts.clone(), Some(project_handle.clone()), cx);
editor.set_vertical_scroll_margin(5, cx);
@ -196,7 +194,7 @@ impl ProjectDiagnosticsEditor {
workspace.activate_item(&existing, cx);
} else {
let workspace_handle = cx.view().downgrade();
let diagnostics = cx.build_view(|cx| {
let diagnostics = cx.new_view(|cx| {
ProjectDiagnosticsEditor::new(workspace.project().clone(), workspace_handle, cx)
});
workspace.add_item(Box::new(diagnostics), cx);
@ -707,7 +705,7 @@ impl Item for ProjectDiagnosticsEditor {
where
Self: Sized,
{
Some(cx.build_view(|cx| {
Some(cx.new_view(|cx| {
ProjectDiagnosticsEditor::new(self.project.clone(), self.workspace.clone(), cx)
}))
}
@ -780,7 +778,7 @@ impl Item for ProjectDiagnosticsEditor {
_item_id: workspace::ItemId,
cx: &mut ViewContext<Pane>,
) -> Task<Result<View<Self>>> {
Task::ready(Ok(cx.build_view(|cx| Self::new(project, workspace, cx))))
Task::ready(Ok(cx.new_view(|cx| Self::new(project, workspace, cx))))
}
}

View file

@ -1,7 +1,7 @@
use collections::HashSet;
use editor::Editor;
use gpui::{
rems, Div, EventEmitter, IntoElement, ParentElement, Render, Styled, Subscription, View,
rems, EventEmitter, IntoElement, ParentElement, Render, Styled, Subscription, View,
ViewContext, WeakView,
};
use language::Diagnostic;
@ -21,9 +21,7 @@ pub struct DiagnosticIndicator {
}
impl Render for DiagnosticIndicator {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) {
(0, 0) => h_stack().child(
IconElement::new(Icon::Check)

View file

@ -1,5 +1,5 @@
use crate::ProjectDiagnosticsEditor;
use gpui::{div, Div, EventEmitter, ParentElement, Render, ViewContext, WeakView};
use gpui::{div, EventEmitter, ParentElement, Render, ViewContext, WeakView};
use ui::prelude::*;
use ui::{Icon, IconButton, Tooltip};
use workspace::{item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
@ -9,9 +9,7 @@ pub struct ToolbarControls {
}
impl Render for ToolbarControls {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let include_warnings = self
.editor
.as_ref()

View file

@ -1046,7 +1046,7 @@ pub mod tests {
}
});
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(
buffer.clone(),
font("Helvetica"),
@ -1286,7 +1286,7 @@ pub mod tests {
let text = "one two three four five\nsix seven eight";
let buffer = MultiBuffer::build_simple(text, cx);
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(
buffer.clone(),
font("Helvetica"),
@ -1393,7 +1393,7 @@ pub mod tests {
let buffer = MultiBuffer::build_simple(&text, cx);
let font_size = px(14.0);
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(buffer.clone(), font("Helvetica"), font_size, None, 1, 1, cx)
});
@ -1464,17 +1464,16 @@ pub mod tests {
cx.update(|cx| init_test(cx, |s| s.defaults.tab_size = Some(2.try_into().unwrap())));
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let font_size = px(14.0);
let map = cx.build_model(|cx| {
DisplayMap::new(buffer, font("Helvetica"), font_size, None, 1, 1, cx)
});
let map = cx
.new_model(|cx| DisplayMap::new(buffer, font("Helvetica"), font_size, None, 1, 1, cx));
assert_eq!(
cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
vec![
@ -1551,15 +1550,15 @@ pub mod tests {
cx.update(|cx| init_test(cx, |_| {}));
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let font_size = px(16.0);
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(buffer, font("Courier"), font_size, Some(px(40.0)), 1, 1, cx)
});
assert_eq!(
@ -1618,17 +1617,17 @@ pub mod tests {
let (text, highlighted_ranges) = marked_text_ranges(r#"constˇ «a»: B = "c «d»""#, false);
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
let font_size = px(16.0);
let map = cx
.build_model(|cx| DisplayMap::new(buffer, font("Courier"), font_size, None, 1, 1, cx));
let map =
cx.new_model(|cx| DisplayMap::new(buffer, font("Courier"), font_size, None, 1, 1, cx));
enum MyType {}
@ -1742,7 +1741,7 @@ pub mod tests {
let buffer = MultiBuffer::build_simple(text, cx);
let font_size = px(14.0);
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(buffer.clone(), font("Helvetica"), font_size, None, 1, 1, cx)
});
let map = map.update(cx, |map, cx| map.snapshot(cx));
@ -1796,7 +1795,7 @@ pub mod tests {
let buffer = MultiBuffer::build_simple("aaa\n\t\tbbb", cx);
let font_size = px(14.0);
let map = cx.build_model(|cx| {
let map = cx.new_model(|cx| {
DisplayMap::new(buffer.clone(), font("Helvetica"), font_size, None, 1, 1, cx)
});
assert_eq!(

View file

@ -74,7 +74,7 @@ impl WrapMap {
wrap_width: Option<Pixels>,
cx: &mut AppContext,
) -> (Model<Self>, WrapSnapshot) {
let handle = cx.build_model(|cx| {
let handle = cx.new_model(|cx| {
let mut this = Self {
font_with_size: (font, font_size),
wrap_width: None,

View file

@ -1637,20 +1637,20 @@ impl InlayHintRefreshReason {
impl Editor {
pub fn single_line(cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::SingleLine, buffer, None, cx)
}
pub fn multi_line(cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::Full, buffer, None, cx)
}
pub fn auto_height(max_lines: usize, cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::AutoHeight { max_lines }, buffer, None, cx)
}
@ -1659,7 +1659,7 @@ impl Editor {
project: Option<Model<Project>>,
cx: &mut ViewContext<Self>,
) -> Self {
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::Full, buffer, project, cx)
}
@ -1693,13 +1693,13 @@ impl Editor {
) -> Self {
let style = cx.text_style();
let font_size = style.font_size.to_pixels(cx.rem_size());
let display_map = cx.build_model(|cx| {
let display_map = cx.new_model(|cx| {
DisplayMap::new(buffer.clone(), style.font(), font_size, None, 2, 1, cx)
});
let selections = SelectionsCollection::new(display_map.clone(), buffer.clone());
let blink_manager = cx.build_model(|cx| BlinkManager::new(CURSOR_BLINK_INTERVAL, cx));
let blink_manager = cx.new_model(|cx| BlinkManager::new(CURSOR_BLINK_INTERVAL, cx));
let soft_wrap_mode_override =
(mode == EditorMode::SingleLine).then(|| language_settings::SoftWrap::None);
@ -1881,7 +1881,7 @@ impl Editor {
.log_err()
{
workspace.add_item(
Box::new(cx.build_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx))),
Box::new(cx.new_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx))),
cx,
);
}
@ -1901,7 +1901,7 @@ impl Editor {
{
workspace.split_item(
action.0,
Box::new(cx.build_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx))),
Box::new(cx.new_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx))),
cx,
);
}
@ -3787,7 +3787,7 @@ impl Editor {
}
let mut ranges_to_highlight = Vec::new();
let excerpt_buffer = cx.build_model(|cx| {
let excerpt_buffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(replica_id).with_title(title);
for (buffer_handle, transaction) in &entries {
let buffer = buffer_handle.read(cx);
@ -3809,7 +3809,7 @@ impl Editor {
workspace.update(&mut cx, |workspace, cx| {
let project = workspace.project().clone();
let editor =
cx.build_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
cx.new_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
workspace.add_item(Box::new(editor.clone()), cx);
editor.update(cx, |editor, cx| {
editor.highlight_background::<Self>(
@ -7494,7 +7494,7 @@ impl Editor {
let mut locations = locations.into_iter().peekable();
let mut ranges_to_highlight = Vec::new();
let excerpt_buffer = cx.build_model(|cx| {
let excerpt_buffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(replica_id);
while let Some(location) = locations.next() {
let buffer = location.buffer.read(cx);
@ -7523,7 +7523,7 @@ impl Editor {
multibuffer.with_title(title)
});
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
Editor::for_multibuffer(excerpt_buffer, Some(workspace.project().clone()), cx)
});
editor.update(cx, |editor, cx| {
@ -7608,7 +7608,7 @@ impl Editor {
// Position the selection in the rename editor so that it matches the current selection.
this.show_local_selections = false;
let rename_editor = cx.build_view(|cx| {
let rename_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, old_name.clone())], None, cx)
@ -9291,9 +9291,7 @@ impl FocusableView for Editor {
}
impl Render for Editor {
type Element = EditorElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render<'a>(&mut self, cx: &mut ViewContext<'a, Self>) -> impl 'static + Element {
let settings = ThemeSettings::get_global(cx);
let text_style = match self.mode {
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {

View file

@ -40,7 +40,7 @@ use workspace::{
fn test_edit_events(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let mut buffer = language::Buffer::new(0, cx.entity_id().as_u64(), "123456");
buffer.set_group_interval(Duration::from_secs(1));
buffer
@ -156,9 +156,9 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let mut now = Instant::now();
let buffer = cx.build_model(|cx| language::Buffer::new(0, cx.entity_id().as_u64(), "123456"));
let buffer = cx.new_model(|cx| language::Buffer::new(0, cx.entity_id().as_u64(), "123456"));
let group_interval = buffer.update(cx, |buffer, _| buffer.transaction_group_interval());
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let editor = cx.add_window(|cx| build_editor(buffer.clone(), cx));
_ = editor.update(cx, |editor, cx| {
@ -226,14 +226,14 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
fn test_ime_composition(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let mut buffer = language::Buffer::new(0, cx.entity_id().as_u64(), "abcde");
// Ensure automatic grouping doesn't occur.
buffer.set_group_interval(Duration::ZERO);
buffer
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
cx.add_window(|cx| {
let mut editor = build_editor(buffer.clone(), cx);
@ -504,9 +504,7 @@ fn test_clone(cx: &mut TestAppContext) {
let cloned_editor = editor
.update(cx, |editor, cx| {
cx.open_window(Default::default(), |cx| {
cx.build_view(|cx| editor.clone(cx))
})
cx.open_window(Default::default(), |cx| cx.new_view(|cx| editor.clone(cx)))
})
.unwrap();
@ -558,7 +556,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) {
.unwrap();
_ = workspace.update(cx, |_v, cx| {
cx.build_view(|cx| {
cx.new_view(|cx| {
let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx);
let mut editor = build_editor(buffer.clone(), cx);
let handle = cx.view();
@ -2349,14 +2347,14 @@ fn test_indent_outdent_with_excerpts(cx: &mut TestAppContext) {
None,
));
let toml_buffer = cx.build_model(|cx| {
let toml_buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n").with_language(toml_language, cx)
});
let rust_buffer = cx.build_model(|cx| {
let rust_buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), "const c: usize = 3;\n")
.with_language(rust_language, cx)
});
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
toml_buffer.clone(),
@ -3907,10 +3905,9 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::EditorEvent>(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
@ -4073,10 +4070,9 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) {
let text = "fn a() {}";
let buffer = cx.build_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
.condition::<crate::EditorEvent>(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx))
@ -4638,10 +4634,9 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::EditorEvent>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
@ -4788,10 +4783,9 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
.condition::<crate::EditorEvent>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
@ -5012,7 +5006,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
cx.executor().start_waiting();
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
_ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
assert!(cx.read(|cx| editor.is_dirty(cx)));
@ -5131,7 +5125,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
cx.executor().start_waiting();
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
_ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
assert!(cx.read(|cx| editor.is_dirty(cx)));
@ -5258,7 +5252,7 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
cx.executor().start_waiting();
let fake_server = fake_servers.next().await.unwrap();
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
_ = editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
@ -6023,9 +6017,8 @@ async fn test_toggle_block_comment(cx: &mut gpui::TestAppContext) {
fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let multibuffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer.clone(),
@ -6108,8 +6101,8 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
primary: None,
}
});
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), initial_text));
let multibuffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), initial_text));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(buffer, excerpt_ranges, cx);
multibuffer
@ -6166,10 +6159,9 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
fn test_refresh_selections(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let mut excerpt1_id = None;
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
excerpt1_id = multibuffer
.push_excerpts(
@ -6252,10 +6244,9 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let mut excerpt1_id = None;
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
excerpt1_id = multibuffer
.push_excerpts(
@ -6348,10 +6339,9 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
"{{} }\n", //
);
let buffer = cx.build_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
});
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::EditorEvent>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
.await;
@ -6479,7 +6469,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
let buffer = project
.create_buffer(&sample_text(16, 8, 'a'), None, cx)
.unwrap();
cx.build_model(|cx| MultiBuffer::singleton(buffer, cx))
cx.new_model(|cx| MultiBuffer::singleton(buffer, cx))
});
let leader = cx.add_window(|cx| build_editor(buffer.clone(), cx));
let follower = cx.update(|cx| {
@ -6491,7 +6481,7 @@ async fn test_following(cx: &mut gpui::TestAppContext) {
)),
..Default::default()
},
|cx| cx.build_view(|cx| build_editor(buffer.clone(), cx)),
|cx| cx.new_view(|cx| build_editor(buffer.clone(), cx)),
)
});
@ -6646,8 +6636,8 @@ async fn test_following_with_multiple_excerpts(cx: &mut gpui::TestAppContext) {
let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx);
let leader = pane.update(cx, |_, cx| {
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
cx.build_view(|cx| build_editor(multibuffer.clone(), cx))
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
cx.new_view(|cx| build_editor(multibuffer.clone(), cx))
});
// Start following the editor when it has no excerpts.
@ -7432,9 +7422,9 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T
let (copilot, copilot_lsp) = Copilot::fake(cx);
_ = cx.update(|cx| cx.set_global(copilot));
let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n"));
let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "c = 3\nd = 4\n"));
let multibuffer = cx.build_model(|cx| {
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n"));
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "c = 3\nd = 4\n"));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer_1.clone(),
@ -7561,7 +7551,7 @@ async fn test_copilot_disabled_globs(executor: BackgroundExecutor, cx: &mut gpui
.await
.unwrap();
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
private_buffer.clone(),
@ -8091,7 +8081,7 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
.unwrap();
let buffer_text = "one\ntwo\nthree\n";
let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
_ = editor.update(cx, |editor, cx| editor.set_text(buffer_text, cx));

View file

@ -2757,7 +2757,7 @@ enum Invisible {
impl Element for EditorElement {
type State = ();
fn layout(
fn request_layout(
&mut self,
_element_state: Option<Self::State>,
cx: &mut gpui::WindowContext,

View file

@ -182,7 +182,7 @@ mod tests {
cx.background_executor.run_until_parked();
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer_1.clone(),

View file

@ -2458,7 +2458,7 @@ pub mod tests {
})
.await
.unwrap();
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer_1.clone(),
@ -2798,7 +2798,7 @@ pub mod tests {
})
.await
.unwrap();
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let (buffer_1_excerpts, buffer_2_excerpts) = multibuffer.update(cx, |multibuffer, cx| {
let buffer_1_excerpts = multibuffer.push_excerpts(
buffer_1.clone(),

View file

@ -7,7 +7,7 @@ use anyhow::{anyhow, Context as _, Result};
use collections::HashSet;
use futures::future::try_join_all;
use gpui::{
div, point, AnyElement, AppContext, AsyncWindowContext, Context, Div, Entity, EntityId,
div, point, AnyElement, AppContext, AsyncWindowContext, Context, Entity, EntityId,
EventEmitter, IntoElement, Model, ParentElement, Pixels, Render, SharedString, Styled,
Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
@ -96,7 +96,7 @@ impl FollowableItem for Editor {
editor
} else {
pane.update(&mut cx, |_, cx| {
let multibuffer = cx.build_model(|cx| {
let multibuffer = cx.new_model(|cx| {
let mut multibuffer;
if state.singleton && buffers.len() == 1 {
multibuffer = MultiBuffer::singleton(buffers.pop().unwrap(), cx)
@ -129,7 +129,7 @@ impl FollowableItem for Editor {
multibuffer
});
cx.build_view(|cx| {
cx.new_view(|cx| {
let mut editor =
Editor::for_multibuffer(multibuffer, Some(project.clone()), cx);
editor.remote_id = Some(remote_id);
@ -632,7 +632,7 @@ impl Item for Editor {
where
Self: Sized,
{
Some(cx.build_view(|cx| self.clone(cx)))
Some(cx.new_view(|cx| self.clone(cx)))
}
fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext<Self>) {
@ -911,7 +911,7 @@ impl Item for Editor {
.downcast::<Buffer>()
.map_err(|_| anyhow!("Project item at stored path was not a buffer"))?;
Ok(pane.update(&mut cx, |_, cx| {
cx.build_view(|cx| {
cx.new_view(|cx| {
let mut editor = Editor::for_buffer(buffer, Some(project), cx);
editor.read_scroll_position_from_db(item_id, workspace_id, cx);
@ -1193,9 +1193,7 @@ impl CursorPosition {
}
impl Render for CursorPosition {
type Element = Div;
fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _: &mut ViewContext<Self>) -> impl Element {
div().when_some(self.position, |el, position| {
let mut text = format!(
"{}{FILE_ROW_COLUMN_DELIMITER}{}",

View file

@ -576,7 +576,7 @@ mod tests {
let buffer = MultiBuffer::build_simple(input_text, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
let display_map =
cx.build_model(|cx| DisplayMap::new(buffer, font, font_size, None, 1, 1, cx));
cx.new_model(|cx| DisplayMap::new(buffer, font, font_size, None, 1, 1, cx));
// add all kinds of inlays between two word boundaries: we should be able to cross them all, when looking for another boundary
let mut id = 0;
@ -763,9 +763,9 @@ mod tests {
let font = font("Helvetica");
let buffer = cx
.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abc\ndefg\nhijkl\nmn"));
let multibuffer = cx.build_model(|cx| {
let buffer =
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abc\ndefg\nhijkl\nmn"));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer.clone(),
@ -784,7 +784,7 @@ mod tests {
multibuffer
});
let display_map =
cx.build_model(|cx| DisplayMap::new(multibuffer, font, px(14.0), None, 2, 2, cx));
cx.new_model(|cx| DisplayMap::new(multibuffer, font, px(14.0), None, 2, 2, cx));
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn");

View file

@ -102,11 +102,11 @@ pub fn expand_macro_recursively(
project.create_buffer(&macro_expansion.expansion, Some(rust_language), cx)
})??;
workspace.update(&mut cx, |workspace, cx| {
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
MultiBuffer::singleton(buffer, cx).with_title(macro_expansion.name)
});
workspace.add_item(
Box::new(cx.build_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx))),
Box::new(cx.new_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx))),
cx,
);
})

View file

@ -30,7 +30,7 @@ pub fn marked_display_snapshot(
let font_size: Pixels = 14usize.into();
let buffer = MultiBuffer::build_simple(&unmarked_text, cx);
let display_map = cx.build_model(|cx| DisplayMap::new(buffer, font, font_size, None, 1, 1, cx));
let display_map = cx.new_model(|cx| DisplayMap::new(buffer, font, font_size, None, 1, 1, cx));
let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx));
let markers = markers
.into_iter()

View file

@ -1,4 +1,4 @@
use gpui::{AnyElement, Render, ViewContext, WeakView};
use gpui::{Render, ViewContext, WeakView};
use ui::{prelude::*, ButtonCommon, Icon, IconButton, Tooltip};
use workspace::{item::ItemHandle, StatusItemView, Workspace};
@ -17,9 +17,7 @@ impl DeployFeedbackButton {
}
impl Render for DeployFeedbackButton {
type Element = AnyElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let is_open = self
.workspace
.upgrade()

View file

@ -7,8 +7,8 @@ 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, red, rems, serde_json, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
Model, PromptLevel, Render, Task, View, ViewContext,
};
use isahc::Request;
use language::Buffer;
@ -154,7 +154,7 @@ impl FeedbackModal {
buffer: Model<Buffer>,
cx: &mut ViewContext<Self>,
) -> Self {
let email_address_editor = cx.build_view(|cx| {
let email_address_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Email address (optional)", cx);
@ -169,7 +169,7 @@ impl FeedbackModal {
let placeholder_text =
"You can use markdown to organize your feedback with code and links.";
let feedback_editor = cx.build_view(|cx| {
let feedback_editor = cx.new_view(|cx| {
let mut editor = Editor::for_buffer(buffer, Some(project.clone()), cx);
editor.set_placeholder_text(placeholder_text, cx);
// editor.set_show_gutter(false, cx);
@ -396,9 +396,7 @@ impl FeedbackModal {
}
impl Render for FeedbackModal {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
self.update_submission_state(cx);
let submit_button_text = if self.awaiting_submission() {

View file

@ -2,7 +2,7 @@ use collections::HashMap;
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
use gpui::{
actions, rems, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Model,
actions, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model,
ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
};
use picker::{Picker, PickerDelegate};
@ -106,7 +106,7 @@ impl FileFinder {
fn new(delegate: FileFinderDelegate, cx: &mut ViewContext<Self>) -> Self {
Self {
picker: cx.build_view(|cx| Picker::new(delegate, cx)),
picker: cx.new_view(|cx| Picker::new(delegate, cx)),
}
}
}
@ -118,9 +118,7 @@ impl FocusableView for FileFinder {
}
}
impl Render for FileFinder {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
v_stack().w(rems(34.)).child(self.picker.clone())
}
}

View file

@ -1,8 +1,7 @@
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor};
use gpui::{
actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, Div, EventEmitter,
FocusHandle, FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext,
VisualContext,
actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, EventEmitter, FocusHandle,
FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext,
};
use text::{Bias, Point};
use theme::ActiveTheme;
@ -50,7 +49,7 @@ impl GoToLine {
}
pub fn new(active_editor: View<Editor>, cx: &mut ViewContext<Self>) -> Self {
let line_editor = cx.build_view(|cx| Editor::single_line(cx));
let line_editor = cx.new_view(|cx| Editor::single_line(cx));
let line_editor_change = cx.subscribe(&line_editor, Self::on_line_editor_event);
let editor = active_editor.read(cx);
@ -153,9 +152,7 @@ impl GoToLine {
}
impl Render for GoToLine {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
div()
.elevation_2(cx)
.key_context("GoToLine")

View file

@ -1105,7 +1105,7 @@ impl Context for AppContext {
/// Build an entity that is owned by the application. The given function will be invoked with
/// a `ModelContext` and must return an object representing the entity. A `Model` will be returned
/// which can be used to access the entity in a context.
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Model<T> {

View file

@ -17,7 +17,7 @@ pub struct AsyncAppContext {
impl Context for AsyncAppContext {
type Result<T> = Result<T>;
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>>
@ -29,7 +29,7 @@ impl Context for AsyncAppContext {
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let mut app = app.borrow_mut();
Ok(app.build_model(build_model))
Ok(app.new_model(build_model))
}
fn update_model<T: 'static, R>(
@ -230,15 +230,14 @@ impl AsyncWindowContext {
impl Context for AsyncWindowContext {
type Result<T> = Result<T>;
fn build_model<T>(
fn new_model<T>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Result<Model<T>>
where
T: 'static,
{
self.window
.update(self, |_, cx| cx.build_model(build_model))
self.window.update(self, |_, cx| cx.new_model(build_model))
}
fn update_model<T: 'static, R>(
@ -281,7 +280,7 @@ impl Context for AsyncWindowContext {
}
impl VisualContext for AsyncWindowContext {
fn build_view<V>(
fn new_view<V>(
&mut self,
build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
) -> Self::Result<View<V>>
@ -289,7 +288,7 @@ impl VisualContext for AsyncWindowContext {
V: 'static + Render,
{
self.window
.update(self, |_, cx| cx.build_view(build_view_state))
.update(self, |_, cx| cx.new_view(build_view_state))
}
fn update_view<V: 'static, R>(

View file

@ -215,11 +215,11 @@ impl<'a, T> ModelContext<'a, T> {
impl<'a, T> Context for ModelContext<'a, T> {
type Result<U> = U;
fn build_model<U: 'static>(
fn new_model<U: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, U>) -> U,
) -> Model<U> {
self.app.build_model(build_model)
self.app.new_model(build_model)
}
fn update_model<U: 'static, R>(

View file

@ -1,6 +1,6 @@
use crate::{
div, Action, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext,
BackgroundExecutor, Bounds, ClipboardItem, Context, Div, Entity, EventEmitter,
BackgroundExecutor, Bounds, ClipboardItem, Context, Element, Entity, EventEmitter,
ForegroundExecutor, InputEvent, KeyDownEvent, Keystroke, Model, ModelContext, Pixels, Platform,
PlatformWindow, Point, Render, Result, Size, Task, TestDispatcher, TestPlatform, TestWindow,
TestWindowHandlers, TextSystem, View, ViewContext, VisualContext, WindowBounds, WindowContext,
@ -23,7 +23,7 @@ pub struct TestAppContext {
impl Context for TestAppContext {
type Result<T> = T;
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>>
@ -31,7 +31,7 @@ impl Context for TestAppContext {
T: 'static,
{
let mut app = self.app.borrow_mut();
app.build_model(build_model)
app.new_model(build_model)
}
fn update_model<T: 'static, R>(
@ -134,15 +134,13 @@ impl TestAppContext {
V: 'static + Render,
{
let mut cx = self.app.borrow_mut();
cx.open_window(WindowOptions::default(), |cx| cx.build_view(build_window))
cx.open_window(WindowOptions::default(), |cx| cx.new_view(build_window))
}
pub fn add_empty_window(&mut self) -> AnyWindowHandle {
let mut cx = self.app.borrow_mut();
cx.open_window(WindowOptions::default(), |cx| {
cx.build_view(|_| EmptyView {})
})
.any_handle
cx.open_window(WindowOptions::default(), |cx| cx.new_view(|_| EmptyView {}))
.any_handle
}
pub fn add_window_view<F, V>(&mut self, build_window: F) -> (View<V>, &mut VisualTestContext)
@ -151,7 +149,7 @@ impl TestAppContext {
V: 'static + Render,
{
let mut cx = self.app.borrow_mut();
let window = cx.open_window(WindowOptions::default(), |cx| cx.build_view(build_window));
let window = cx.open_window(WindowOptions::default(), |cx| cx.new_view(build_window));
drop(cx);
let view = window.root_view(self).unwrap();
let cx = Box::new(VisualTestContext::from_window(*window.deref(), self));
@ -617,11 +615,11 @@ impl<'a> VisualTestContext<'a> {
impl<'a> Context for VisualTestContext<'a> {
type Result<T> = <TestAppContext as Context>::Result<T>;
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>> {
self.cx.build_model(build_model)
self.cx.new_model(build_model)
}
fn update_model<T, R>(
@ -666,7 +664,7 @@ impl<'a> Context for VisualTestContext<'a> {
}
impl<'a> VisualContext for VisualTestContext<'a> {
fn build_view<V>(
fn new_view<V>(
&mut self,
build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
) -> Self::Result<View<V>>
@ -674,7 +672,7 @@ impl<'a> VisualContext for VisualTestContext<'a> {
V: 'static + Render,
{
self.window
.update(self.cx, |_, cx| cx.build_view(build_view))
.update(self.cx, |_, cx| cx.new_view(build_view))
.unwrap()
}
@ -726,16 +724,14 @@ impl AnyWindowHandle {
cx: &mut TestAppContext,
build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
) -> View<V> {
self.update(cx, |_, cx| cx.build_view(build_view)).unwrap()
self.update(cx, |_, cx| cx.new_view(build_view)).unwrap()
}
}
pub struct EmptyView {}
impl Render for EmptyView {
type Element = Div;
fn render(&mut self, _cx: &mut crate::ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut crate::ViewContext<Self>) -> impl Element {
div()
}
}

View file

@ -6,23 +6,42 @@ use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
use std::{any::Any, fmt::Debug};
pub trait Render: 'static + Sized {
type Element: Element + 'static;
pub trait Element: 'static + IntoElement {
type State: 'static;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element;
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State);
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext);
fn into_any(self) -> AnyElement {
AnyElement::new(self)
}
}
/// Implemented by any type that can be converted into an element.
pub trait IntoElement: Sized {
type Element: Element + 'static;
/// The specific type of element into which the implementing type is converted.
type Element: Element;
/// The [ElementId] of self once converted into an [Element].
/// If present, the resulting element's state will be carried across frames.
fn element_id(&self) -> Option<ElementId>;
/// Convert self into a type that implements [Element].
fn into_element(self) -> Self::Element;
/// Convert self into a dynamically-typed [AnyElement].
fn into_any_element(self) -> AnyElement {
self.into_element().into_any()
}
/// Convert into an element, then draw in the current window at the given origin.
/// The provided available space is provided to the layout engine to determine the size of the root element.
/// Once the element is drawn, its associated element staet is yielded to the given callback.
fn draw_and_update_state<T, R>(
self,
origin: Point<Pixels>,
@ -54,6 +73,7 @@ pub trait IntoElement: Sized {
}
}
/// Convert self to another type by calling the given closure. Useful in rendering code.
fn map<U>(self, f: impl FnOnce(Self) -> U) -> U
where
Self: Sized,
@ -62,6 +82,7 @@ pub trait IntoElement: Sized {
f(self)
}
/// Conditionally chain onto self with the given closure. Useful in rendering code.
fn when(self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self
where
Self: Sized,
@ -69,6 +90,8 @@ pub trait IntoElement: Sized {
self.map(|this| if condition { then(this) } else { this })
}
/// Conditionally chain onto self with the given closure if the given option is Some.
/// The contents of the option are provided to the closure.
fn when_some<T>(self, option: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self
where
Self: Sized,
@ -83,26 +106,37 @@ pub trait IntoElement: Sized {
}
}
pub trait Element: 'static + IntoElement {
type State: 'static;
fn layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State);
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext);
fn into_any(self) -> AnyElement {
AnyElement::new(self)
}
pub trait Render: 'static + Sized {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element;
}
/// You can derive [IntoElement] on any type that implements this trait.
/// It is used to allow views to be expressed in terms of abstract data.
pub trait RenderOnce: 'static {
type Rendered: IntoElement;
type Output: IntoElement;
fn render(self, cx: &mut WindowContext) -> Self::Rendered;
fn render(self, cx: &mut WindowContext) -> Self::Output;
}
pub trait ParentElement {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]>;
fn child(mut self, child: impl IntoElement) -> Self
where
Self: Sized,
{
self.children_mut().push(child.into_element().into_any());
self
}
fn children(mut self, children: impl IntoIterator<Item = impl IntoElement>) -> Self
where
Self: Sized,
{
self.children_mut()
.extend(children.into_iter().map(|child| child.into_any_element()));
self
}
}
pub struct Component<C> {
@ -110,8 +144,8 @@ pub struct Component<C> {
}
pub struct ComponentState<C: RenderOnce> {
rendered_element: Option<<C::Rendered as IntoElement>::Element>,
rendered_element_state: Option<<<C::Rendered as IntoElement>::Element as Element>::State>,
rendered_element: Option<<C::Output as IntoElement>::Element>,
rendered_element_state: Option<<<C::Output as IntoElement>::Element as Element>::State>,
}
impl<C> Component<C> {
@ -125,7 +159,7 @@ impl<C> Component<C> {
impl<C: RenderOnce> Element for Component<C> {
type State = ComponentState<C>;
fn layout(
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
@ -133,7 +167,7 @@ impl<C: RenderOnce> Element for Component<C> {
let mut element = self.component.take().unwrap().render(cx).into_element();
if let Some(element_id) = element.element_id() {
let layout_id =
cx.with_element_state(element_id, |state, cx| element.layout(state, cx));
cx.with_element_state(element_id, |state, cx| element.request_layout(state, cx));
let state = ComponentState {
rendered_element: Some(element),
rendered_element_state: None,
@ -141,7 +175,7 @@ impl<C: RenderOnce> Element for Component<C> {
(layout_id, state)
} else {
let (layout_id, state) =
element.layout(state.and_then(|s| s.rendered_element_state), cx);
element.request_layout(state.and_then(|s| s.rendered_element_state), cx);
let state = ComponentState {
rendered_element: Some(element),
rendered_element_state: Some(state),
@ -183,27 +217,6 @@ impl<C: RenderOnce> IntoElement for Component<C> {
#[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)]
pub struct GlobalElementId(SmallVec<[ElementId; 32]>);
pub trait ParentElement {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]>;
fn child(mut self, child: impl IntoElement) -> Self
where
Self: Sized,
{
self.children_mut().push(child.into_element().into_any());
self
}
fn children(mut self, children: impl IntoIterator<Item = impl IntoElement>) -> Self
where
Self: Sized,
{
self.children_mut()
.extend(children.into_iter().map(|child| child.into_any_element()));
self
}
}
trait ElementObject {
fn element_id(&self) -> Option<ElementId>;
@ -258,15 +271,18 @@ impl<E: Element> DrawableElement<E> {
self.element.as_ref()?.element_id()
}
fn layout(&mut self, cx: &mut WindowContext) -> LayoutId {
fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
let (layout_id, frame_state) = if let Some(id) = self.element.as_ref().unwrap().element_id()
{
let layout_id = cx.with_element_state(id, |element_state, cx| {
self.element.as_mut().unwrap().layout(element_state, cx)
self.element
.as_mut()
.unwrap()
.request_layout(element_state, cx)
});
(layout_id, None)
} else {
let (layout_id, frame_state) = self.element.as_mut().unwrap().layout(None, cx);
let (layout_id, frame_state) = self.element.as_mut().unwrap().request_layout(None, cx);
(layout_id, Some(frame_state))
};
@ -325,7 +341,7 @@ impl<E: Element> DrawableElement<E> {
cx: &mut WindowContext,
) -> Size<Pixels> {
if matches!(&self.phase, ElementDrawPhase::Start) {
self.layout(cx);
self.request_layout(cx);
}
let layout_id = match &mut self.phase {
@ -380,7 +396,7 @@ where
}
fn layout(&mut self, cx: &mut WindowContext) -> LayoutId {
DrawableElement::layout(self.as_mut().unwrap(), cx)
DrawableElement::request_layout(self.as_mut().unwrap(), cx)
}
fn paint(&mut self, cx: &mut WindowContext) {
@ -454,7 +470,7 @@ impl AnyElement {
impl Element for AnyElement {
type State = ();
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,
@ -502,7 +518,7 @@ impl IntoElement for () {
impl Element for () {
type State = ();
fn layout(
fn request_layout(
&mut self,
_state: Option<Self::State>,
cx: &mut WindowContext,
@ -520,9 +536,7 @@ impl Element for () {
}
impl Render for () {
type Element = Self;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
()
}
}

View file

@ -29,7 +29,7 @@ impl IntoElement for Canvas {
impl Element for Canvas {
type State = Style;
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,

View file

@ -768,7 +768,7 @@ impl ParentElement for Div {
impl Element for Div {
type State = DivState;
fn layout(
fn request_layout(
&mut self,
element_state: Option<Self::State>,
cx: &mut WindowContext,
@ -1818,12 +1818,12 @@ where
{
type State = E::State;
fn layout(
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State) {
self.element.layout(state, cx)
self.element.request_layout(state, cx)
}
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {
@ -1892,12 +1892,12 @@ where
{
type State = E::State;
fn layout(
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State) {
self.element.layout(state, cx)
self.element.request_layout(state, cx)
}
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {

View file

@ -71,7 +71,7 @@ impl Img {
impl Element for Img {
type State = InteractiveElementState;
fn layout(
fn request_layout(
&mut self,
element_state: Option<Self::State>,
cx: &mut WindowContext,

View file

@ -302,7 +302,7 @@ pub struct ListOffset {
impl Element for List {
type State = ();
fn layout(
fn request_layout(
&mut self,
_state: Option<Self::State>,
cx: &mut crate::WindowContext,

View file

@ -60,7 +60,7 @@ impl ParentElement for Overlay {
impl Element for Overlay {
type State = OverlayState;
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,

View file

@ -26,7 +26,7 @@ impl Svg {
impl Element for Svg {
type State = InteractiveElementState;
fn layout(
fn request_layout(
&mut self,
element_state: Option<Self::State>,
cx: &mut WindowContext,

View file

@ -12,7 +12,7 @@ use util::ResultExt;
impl Element for &'static str {
type State = TextState;
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,
@ -42,7 +42,7 @@ impl IntoElement for &'static str {
impl Element for SharedString {
type State = TextState;
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,
@ -118,7 +118,7 @@ impl StyledText {
impl Element for StyledText {
type State = TextState;
fn layout(
fn request_layout(
&mut self,
_: Option<Self::State>,
cx: &mut WindowContext,
@ -331,7 +331,7 @@ impl InteractiveText {
impl Element for InteractiveText {
type State = InteractiveTextState;
fn layout(
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
@ -340,14 +340,14 @@ impl Element for InteractiveText {
mouse_down_index, ..
}) = state
{
let (layout_id, text_state) = self.text.layout(None, cx);
let (layout_id, text_state) = self.text.request_layout(None, cx);
let element_state = InteractiveTextState {
text_state,
mouse_down_index,
};
(layout_id, element_state)
} else {
let (layout_id, text_state) = self.text.layout(None, cx);
let (layout_id, text_state) = self.text.request_layout(None, cx);
let element_state = InteractiveTextState {
text_state,
mouse_down_index: Rc::default(),

View file

@ -116,7 +116,7 @@ pub struct UniformListState {
impl Element for UniformList {
type State = UniformListState;
fn layout(
fn request_layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,

View file

@ -85,7 +85,7 @@ use taffy::TaffyLayoutEngine;
pub trait Context {
type Result<T>;
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Self::Result<Model<T>>;
@ -120,7 +120,7 @@ pub trait Context {
}
pub trait VisualContext: Context {
fn build_view<V>(
fn new_view<V>(
&mut self,
build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
) -> Self::Result<View<V>>

View file

@ -1,5 +1,5 @@
use crate::{
div, point, Div, Element, IntoElement, Keystroke, Modifiers, Pixels, Point, Render, ViewContext,
div, point, Element, IntoElement, Keystroke, Modifiers, Pixels, Point, Render, ViewContext,
};
use smallvec::SmallVec;
use std::{any::Any, fmt::Debug, marker::PhantomData, ops::Deref, path::PathBuf};
@ -205,9 +205,7 @@ impl ExternalPaths {
}
impl Render for ExternalPaths {
type Element = Div;
fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _: &mut ViewContext<Self>) -> impl Element {
div() // Intentionally left empty because the platform will render icons for the dragged files
}
}
@ -292,8 +290,8 @@ impl InputEvent {
#[cfg(test)]
mod test {
use crate::{
self as gpui, div, Div, FocusHandle, InteractiveElement, IntoElement, KeyBinding,
Keystroke, ParentElement, Render, Stateful, TestAppContext, VisualContext,
self as gpui, div, Element, FocusHandle, InteractiveElement, IntoElement, KeyBinding,
Keystroke, ParentElement, Render, TestAppContext, VisualContext,
};
struct TestView {
@ -305,9 +303,7 @@ mod test {
actions!(test, [TestAction]);
impl Render for TestView {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
div().id("testview").child(
div()
.key_context("parent")
@ -331,7 +327,7 @@ mod test {
fn test_on_events(cx: &mut TestAppContext) {
let window = cx.update(|cx| {
cx.open_window(Default::default(), |cx| {
cx.build_view(|cx| TestView {
cx.new_view(|cx| TestView {
saw_key_down: false,
saw_action: false,
focus_handle: cx.focus_handle(),

View file

@ -13,23 +13,13 @@ mod window;
mod window_appearence;
use crate::{px, size, GlobalPixels, Pixels, Size};
use anyhow::anyhow;
use cocoa::{
base::{id, nil},
foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger, NSURL},
foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger},
};
use metal_renderer::*;
use objc::{
msg_send,
runtime::{BOOL, NO, YES},
sel, sel_impl,
};
use std::{
ffi::{c_char, CStr, OsStr},
ops::Range,
os::unix::prelude::OsStrExt,
path::PathBuf,
};
use objc::runtime::{BOOL, NO, YES};
use std::ops::Range;
pub use dispatcher::*;
pub use display::*;
@ -147,19 +137,3 @@ impl From<NSRect> for Size<GlobalPixels> {
// && self.origin.y + self.size.height >= other.origin.y
// }
// }
// todo!
#[allow(unused)]
unsafe fn ns_url_to_path(url: id) -> crate::Result<PathBuf> {
let path: *mut c_char = msg_send![url, fileSystemRepresentation];
if path.is_null() {
Err(anyhow!(
"url is not a file path: {}",
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
))
} else {
Ok(PathBuf::from(OsStr::from_bytes(
CStr::from_ptr(path).to_bytes(),
)))
}
}

View file

@ -34,8 +34,6 @@ unsafe fn build_event_source() {
mem::forget(source);
}
// todo!
#[allow(unused)]
pub fn key_to_native(key: &str) -> Cow<str> {
use cocoa::appkit::*;
let code = match key {

View file

@ -74,7 +74,6 @@ const NSWindowAnimationBehaviorUtilityWindow: NSInteger = 4;
#[allow(non_upper_case_globals)]
const NSViewLayerContentsRedrawDuringViewResize: NSInteger = 2;
// https://developer.apple.com/documentation/appkit/nsdragoperation
#[allow(non_upper_case_globals)]
type NSDragOperation = NSUInteger;
#[allow(non_upper_case_globals)]
const NSDragOperationNone: NSDragOperation = 0;

View file

@ -172,7 +172,6 @@ pub struct Scene {
}
impl Scene {
#[allow(dead_code)]
pub fn paths(&self) -> &[Path<ScaledPixels>] {
&self.paths
}

View file

@ -81,12 +81,12 @@ impl<V: 'static> View<V> {
impl<V: Render> Element for View<V> {
type State = Option<AnyElement>;
fn layout(
fn request_layout(
&mut self,
_state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State) {
let mut element = self.update(cx, |view, cx| view.render(cx).into_any());
let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx);
(layout_id, Some(element))
}
@ -229,7 +229,7 @@ impl<V: Render> From<View<V>> for AnyView {
impl Element for AnyView {
type State = Option<AnyElement>;
fn layout(
fn request_layout(
&mut self,
_state: Option<Self::State>,
cx: &mut WindowContext,
@ -312,27 +312,15 @@ impl std::fmt::Debug for AnyWeakView {
}
}
impl<T, E> Render for T
where
T: 'static + FnMut(&mut WindowContext) -> E,
E: 'static + Send + Element,
{
type Element = E;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
(self)(cx)
}
}
mod any_view {
use crate::{AnyElement, AnyView, Element, LayoutId, Render, WindowContext};
use crate::{AnyElement, AnyView, IntoElement, LayoutId, Render, WindowContext};
pub(crate) fn layout<V: 'static + Render>(
view: &AnyView,
cx: &mut WindowContext,
) -> (LayoutId, AnyElement) {
let view = view.clone().downcast::<V>().unwrap();
let mut element = view.update(cx, |view, cx| view.render(cx).into_any());
let mut element = view.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx);
(layout_id, element)
}

View file

@ -1463,7 +1463,7 @@ impl<'a> WindowContext<'a> {
if self.active_drag.is_none() {
self.active_drag = Some(AnyDrag {
value: Box::new(files.clone()),
view: self.build_view(|_| files).into(),
view: self.new_view(|_| files).into(),
cursor_offset: position,
});
}
@ -1842,10 +1842,7 @@ impl<'a> WindowContext<'a> {
impl Context for WindowContext<'_> {
type Result<T> = T;
fn build_model<T>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Model<T>
fn new_model<T>(&mut self, build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T) -> Model<T>
where
T: 'static,
{
@ -1916,7 +1913,7 @@ impl Context for WindowContext<'_> {
}
impl VisualContext for WindowContext<'_> {
fn build_view<V>(
fn new_view<V>(
&mut self,
build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
) -> Self::Result<View<V>>
@ -1962,7 +1959,7 @@ impl VisualContext for WindowContext<'_> {
where
V: 'static + Render,
{
let view = self.build_view(build_view);
let view = self.new_view(build_view);
self.window.root_view = Some(view.clone().into());
self.notify();
view
@ -2728,11 +2725,11 @@ impl<'a, V: 'static> ViewContext<'a, V> {
impl<V> Context for ViewContext<'_, V> {
type Result<U> = U;
fn build_model<T: 'static>(
fn new_model<T: 'static>(
&mut self,
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
) -> Model<T> {
self.window_cx.build_model(build_model)
self.window_cx.new_model(build_model)
}
fn update_model<T: 'static, R>(
@ -2774,11 +2771,11 @@ impl<V> Context for ViewContext<'_, V> {
}
impl<V: 'static> VisualContext for ViewContext<'_, V> {
fn build_view<W: Render + 'static>(
fn new_view<W: Render + 'static>(
&mut self,
build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
) -> Self::Result<View<W>> {
self.window_cx.build_view(build_view_state)
self.window_cx.new_view(build_view_state)
}
fn update_view<V2: 'static, R>(

View file

@ -11,9 +11,7 @@ pub fn derive_render(input: TokenStream) -> TokenStream {
impl #impl_generics gpui::Render for #type_name #type_generics
#where_clause
{
type Element = ();
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
()
}
}

View file

@ -42,7 +42,7 @@ fn init_logger() {
fn test_line_endings(cx: &mut gpui::AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "one\r\ntwo\rthree")
.with_language(Arc::new(rust_lang()), cx);
assert_eq!(buffer.text(), "one\ntwo\nthree");
@ -138,8 +138,8 @@ fn test_edit_events(cx: &mut gpui::AppContext) {
let buffer_1_events = Arc::new(Mutex::new(Vec::new()));
let buffer_2_events = Arc::new(Mutex::new(Vec::new()));
let buffer1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcdef"));
let buffer2 = cx.build_model(|cx| Buffer::new(1, cx.entity_id().as_u64(), "abcdef"));
let buffer1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcdef"));
let buffer2 = cx.new_model(|cx| Buffer::new(1, cx.entity_id().as_u64(), "abcdef"));
let buffer1_ops = Arc::new(Mutex::new(Vec::new()));
buffer1.update(cx, {
let buffer1_ops = buffer1_ops.clone();
@ -218,7 +218,7 @@ fn test_edit_events(cx: &mut gpui::AppContext) {
#[gpui::test]
async fn test_apply_diff(cx: &mut TestAppContext) {
let text = "a\nbb\nccc\ndddd\neeeee\nffffff\n";
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
let anchor = buffer.update(cx, |buffer, _| buffer.anchor_before(Point::new(3, 3)));
let text = "a\nccc\ndddd\nffffff\n";
@ -250,7 +250,7 @@ async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) {
]
.join("\n");
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
// Spawn a task to format the buffer's whitespace.
// Pause so that the foratting task starts running.
@ -314,7 +314,7 @@ async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) {
#[gpui::test]
async fn test_reparse(cx: &mut gpui::TestAppContext) {
let text = "fn a() {}";
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
});
@ -442,7 +442,7 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) {
#[gpui::test]
async fn test_resetting_language(cx: &mut gpui::TestAppContext) {
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let mut buffer =
Buffer::new(0, cx.entity_id().as_u64(), "{}").with_language(Arc::new(rust_lang()), cx);
buffer.set_sync_parse_timeout(Duration::ZERO);
@ -492,7 +492,7 @@ async fn test_outline(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
});
let outline = buffer
@ -578,7 +578,7 @@ async fn test_outline_nodes_with_newlines(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
});
let outline = buffer
@ -616,7 +616,7 @@ async fn test_outline_with_extra_context(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(language), cx)
});
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
@ -660,7 +660,7 @@ async fn test_symbols_containing(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
});
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
@ -881,7 +881,7 @@ fn test_enclosing_bracket_ranges_where_brackets_are_not_outermost_children(cx: &
#[gpui::test]
fn test_range_for_syntax_ancestor(cx: &mut AppContext) {
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "fn a() { b(|c| {}) }";
let buffer =
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
@ -922,7 +922,7 @@ fn test_range_for_syntax_ancestor(cx: &mut AppContext) {
fn test_autoindent_with_soft_tabs(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "fn a() {}";
let mut buffer =
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
@ -965,7 +965,7 @@ fn test_autoindent_with_hard_tabs(cx: &mut AppContext) {
settings.defaults.hard_tabs = Some(true);
});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "fn a() {}";
let mut buffer =
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
@ -1006,7 +1006,7 @@ fn test_autoindent_with_hard_tabs(cx: &mut AppContext) {
fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let entity_id = cx.entity_id();
let mut buffer = Buffer::new(
0,
@ -1080,7 +1080,7 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
buffer
});
cx.build_model(|cx| {
cx.new_model(|cx| {
eprintln!("second buffer: {:?}", cx.entity_id());
let mut buffer = Buffer::new(
@ -1147,7 +1147,7 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
fn test_autoindent_does_not_adjust_lines_within_newly_created_errors(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let mut buffer = Buffer::new(
0,
cx.entity_id().as_u64(),
@ -1209,7 +1209,7 @@ fn test_autoindent_does_not_adjust_lines_within_newly_created_errors(cx: &mut Ap
fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let mut buffer = Buffer::new(
0,
cx.entity_id().as_u64(),
@ -1266,7 +1266,7 @@ fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut AppContext) {
fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "a\nb";
let mut buffer =
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
@ -1284,7 +1284,7 @@ fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut AppContext) {
fn test_autoindent_multi_line_insertion(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "
const a: usize = 1;
fn b() {
@ -1326,7 +1326,7 @@ fn test_autoindent_multi_line_insertion(cx: &mut AppContext) {
fn test_autoindent_block_mode(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = r#"
fn a() {
b();
@ -1410,7 +1410,7 @@ fn test_autoindent_block_mode(cx: &mut AppContext) {
fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = r#"
fn a() {
if b() {
@ -1490,7 +1490,7 @@ fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut AppContex
fn test_autoindent_language_without_indents_query(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = "
* one
- a
@ -1559,7 +1559,7 @@ fn test_autoindent_with_injected_languages(cx: &mut AppContext) {
language_registry.add(html_language.clone());
language_registry.add(javascript_language.clone());
cx.build_model(|cx| {
cx.new_model(|cx| {
let (text, ranges) = marked_text_ranges(
&"
<div>ˇ
@ -1610,7 +1610,7 @@ fn test_autoindent_query_with_outdent_captures(cx: &mut AppContext) {
settings.defaults.tab_size = Some(2.try_into().unwrap());
});
cx.build_model(|cx| {
cx.new_model(|cx| {
let mut buffer =
Buffer::new(0, cx.entity_id().as_u64(), "").with_language(Arc::new(ruby_lang()), cx);
@ -1653,7 +1653,7 @@ fn test_autoindent_query_with_outdent_captures(cx: &mut AppContext) {
fn test_language_scope_at_with_javascript(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let language = Language::new(
LanguageConfig {
name: "JavaScript".into(),
@ -1786,7 +1786,7 @@ fn test_language_scope_at_with_javascript(cx: &mut AppContext) {
fn test_language_scope_at_with_rust(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let language = Language::new(
LanguageConfig {
name: "Rust".into(),
@ -1854,7 +1854,7 @@ fn test_language_scope_at_with_rust(cx: &mut AppContext) {
fn test_language_scope_at_with_combined_injections(cx: &mut AppContext) {
init_settings(cx, |_| {});
cx.build_model(|cx| {
cx.new_model(|cx| {
let text = r#"
<ol>
<% people.each do |person| %>
@ -1902,7 +1902,7 @@ fn test_language_scope_at_with_combined_injections(cx: &mut AppContext) {
fn test_serialization(cx: &mut gpui::AppContext) {
let mut now = Instant::now();
let buffer1 = cx.build_model(|cx| {
let buffer1 = cx.new_model(|cx| {
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "abc");
buffer.edit([(3..3, "D")], None, cx);
@ -1925,7 +1925,7 @@ fn test_serialization(cx: &mut gpui::AppContext) {
let ops = cx
.background_executor()
.block(buffer1.read(cx).serialize_ops(None, cx));
let buffer2 = cx.build_model(|cx| {
let buffer2 = cx.new_model(|cx| {
let mut buffer = Buffer::from_proto(1, state, None).unwrap();
buffer
.apply_ops(
@ -1959,10 +1959,10 @@ fn test_random_collaboration(cx: &mut AppContext, mut rng: StdRng) {
let mut buffers = Vec::new();
let network = Arc::new(Mutex::new(Network::new(rng.clone())));
let base_buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text.as_str()));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text.as_str()));
for i in 0..rng.gen_range(min_peers..=max_peers) {
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
let state = base_buffer.read(cx).to_proto();
let ops = cx
.background_executor()
@ -2082,7 +2082,7 @@ fn test_random_collaboration(cx: &mut AppContext, mut rng: StdRng) {
new_replica_id,
replica_id
);
new_buffer = Some(cx.build_model(|cx| {
new_buffer = Some(cx.new_model(|cx| {
let mut new_buffer =
Buffer::from_proto(new_replica_id, old_buffer_state, None).unwrap();
new_buffer
@ -2460,7 +2460,7 @@ fn assert_bracket_pairs(
cx: &mut AppContext,
) {
let (expected_text, selection_ranges) = marked_text_ranges(selection_text, false);
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), expected_text.clone())
.with_language(Arc::new(language), cx)
});

View file

@ -1,6 +1,6 @@
use editor::Editor;
use gpui::{
div, Div, IntoElement, ParentElement, Render, Subscription, View, ViewContext, WeakView,
div, Element, IntoElement, ParentElement, Render, Subscription, View, ViewContext, WeakView,
};
use std::sync::Arc;
use ui::{Button, ButtonCommon, Clickable, LabelSize, Tooltip};
@ -38,9 +38,7 @@ impl ActiveBufferLanguage {
}
impl Render for ActiveBufferLanguage {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Div {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
div().when_some(self.active_language.as_ref(), |el, active_language| {
let active_language_text = if let Some(active_language_text) = active_language {
active_language_text.to_string()

View file

@ -5,7 +5,7 @@ use anyhow::anyhow;
use editor::Editor;
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
use gpui::{
actions, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Model,
actions, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Model,
ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
};
use language::{Buffer, LanguageRegistry};
@ -61,15 +61,13 @@ impl LanguageSelector {
language_registry,
);
let picker = cx.build_view(|cx| Picker::new(delegate, cx));
let picker = cx.new_view(|cx| Picker::new(delegate, cx));
Self { picker }
}
}
impl Render for LanguageSelector {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
v_stack().w(rems(34.)).child(self.picker.clone())
}
}

View file

@ -1,10 +1,10 @@
use collections::{HashMap, VecDeque};
use editor::{Editor, EditorElement, EditorEvent, MoveToEnd};
use editor::{Editor, EditorEvent, MoveToEnd};
use futures::{channel::mpsc, StreamExt};
use gpui::{
actions, div, AnchorCorner, AnyElement, AppContext, Context, Div, EventEmitter, FocusHandle,
FocusableView, IntoElement, Model, ModelContext, ParentElement, Render, Styled, Subscription,
View, ViewContext, VisualContext, WeakModel, WindowContext,
actions, div, AnchorCorner, AnyElement, AppContext, Context, Element, EventEmitter,
FocusHandle, FocusableView, IntoElement, Model, ModelContext, ParentElement, Render, Styled,
Subscription, View, ViewContext, VisualContext, WeakModel, WindowContext,
};
use language::{LanguageServerId, LanguageServerName};
use lsp::IoKind;
@ -78,7 +78,7 @@ pub(crate) struct LogMenuItem {
actions!(debug, [OpenLanguageServerLogs]);
pub fn init(cx: &mut AppContext) {
let log_store = cx.build_model(|cx| LogStore::new(cx));
let log_store = cx.new_model(|cx| LogStore::new(cx));
cx.observe_new_views(move |workspace: &mut Workspace, cx| {
let project = workspace.project();
@ -93,7 +93,7 @@ pub fn init(cx: &mut AppContext) {
let project = workspace.project().read(cx);
if project.is_local() {
workspace.add_item(
Box::new(cx.build_view(|cx| {
Box::new(cx.new_view(|cx| {
LspLogView::new(workspace.project().clone(), log_store.clone(), cx)
})),
cx,
@ -444,7 +444,7 @@ impl LspLogView {
log_contents: String,
cx: &mut ViewContext<Self>,
) -> (View<Editor>, Subscription) {
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
let mut editor = Editor::multi_line(cx);
editor.set_text(log_contents, cx);
editor.move_to_end(&MoveToEnd, cx);
@ -595,10 +595,9 @@ fn log_contents(lines: &VecDeque<String>) -> String {
}
impl Render for LspLogView {
type Element = EditorElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
self.editor.update(cx, |editor, cx| editor.render(cx))
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
self.editor
.update(cx, |editor, cx| editor.render(cx).into_any())
}
}
@ -709,9 +708,7 @@ impl ToolbarItemView for LspLogToolbarItemView {
}
impl Render for LspLogToolbarItemView {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let Some(log_view) = self.log_view.clone() else {
return div();
};

View file

@ -46,7 +46,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
project.languages().add(Arc::new(rust_language));
});
let log_store = cx.build_model(|cx| LogStore::new(cx));
let log_store = cx.new_model(|cx| LogStore::new(cx));
log_store.update(cx, |store, cx| store.add_project(&project, cx));
let _rust_buffer = project

View file

@ -1,6 +1,6 @@
use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId};
use gpui::{
actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div,
actions, canvas, div, rems, uniform_list, AnyElement, AppContext, AvailableSpace, Div, Element,
EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model,
MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled,
UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext,
@ -24,7 +24,7 @@ pub fn init(cx: &mut AppContext) {
let active_item = workspace.active_item(cx);
let workspace_handle = workspace.weak_handle();
let syntax_tree_view =
cx.build_view(|cx| SyntaxTreeView::new(workspace_handle, active_item, cx));
cx.new_view(|cx| SyntaxTreeView::new(workspace_handle, active_item, cx));
workspace.split_item(SplitDirection::Right, Box::new(syntax_tree_view), cx)
});
})
@ -305,9 +305,7 @@ impl SyntaxTreeView {
}
impl Render for SyntaxTreeView {
type Element = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> impl Element {
let settings = ThemeSettings::get_global(cx);
let line_height = cx
.text_style()
@ -419,7 +417,7 @@ impl Item for SyntaxTreeView {
where
Self: Sized,
{
Some(cx.build_view(|cx| {
Some(cx.new_view(|cx| {
let mut clone = Self::new(self.workspace_handle.clone(), None, cx);
if let Some(editor) = &self.editor {
clone.set_editor(editor.editor.clone(), cx)
@ -507,9 +505,7 @@ fn format_node_range(node: Node) -> String {
}
impl Render for SyntaxTreeToolbarItemView {
type Element = PopoverMenu<ContextMenu>;
fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> PopoverMenu<ContextMenu> {
fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> impl Element {
self.render_menu(cx)
.unwrap_or_else(|| popover_menu("Empty Syntax Tree"))
}

View file

@ -1649,17 +1649,17 @@ impl MultiBuffer {
#[cfg(any(test, feature = "test-support"))]
impl MultiBuffer {
pub fn build_simple(text: &str, cx: &mut gpui::AppContext) -> Model<Self> {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
cx.build_model(|cx| Self::singleton(buffer, cx))
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
cx.new_model(|cx| Self::singleton(buffer, cx))
}
pub fn build_multi<const COUNT: usize>(
excerpts: [(&str, Vec<Range<Point>>); COUNT],
cx: &mut gpui::AppContext,
) -> Model<Self> {
let multi = cx.build_model(|_| Self::new(0));
let multi = cx.new_model(|_| Self::new(0));
for (text, ranges) in excerpts {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
let excerpt_ranges = ranges.into_iter().map(|range| ExcerptRange {
context: range,
primary: None,
@ -1673,11 +1673,11 @@ impl MultiBuffer {
}
pub fn build_from_buffer(buffer: Model<Buffer>, cx: &mut gpui::AppContext) -> Model<Self> {
cx.build_model(|cx| Self::singleton(buffer, cx))
cx.new_model(|cx| Self::singleton(buffer, cx))
}
pub fn build_random(rng: &mut impl rand::Rng, cx: &mut gpui::AppContext) -> Model<Self> {
cx.build_model(|cx| {
cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
let mutation_count = rng.gen_range(1..=5);
multibuffer.randomly_edit_excerpts(rng, mutation_count, cx);
@ -1748,8 +1748,7 @@ impl MultiBuffer {
if excerpt_ids.is_empty() || (rng.gen() && excerpt_ids.len() < max_excerpts) {
let buffer_handle = if rng.gen() || self.buffers.borrow().is_empty() {
let text = RandomCharIter::new(&mut *rng).take(10).collect::<String>();
buffers
.push(cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)));
buffers.push(cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)));
let buffer = buffers.last().unwrap().read(cx);
log::info!(
"Creating new buffer {} with text: {:?}",
@ -4144,8 +4143,8 @@ mod tests {
#[gpui::test]
fn test_singleton(cx: &mut AppContext) {
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
let multibuffer = cx.build_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
let multibuffer = cx.new_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
let snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(snapshot.text(), buffer.read(cx).text());
@ -4171,8 +4170,8 @@ mod tests {
#[gpui::test]
fn test_remote(cx: &mut AppContext) {
let host_buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a"));
let guest_buffer = cx.build_model(|cx| {
let host_buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a"));
let guest_buffer = cx.new_model(|cx| {
let state = host_buffer.read(cx).to_proto();
let ops = cx
.background_executor()
@ -4187,7 +4186,7 @@ mod tests {
.unwrap();
buffer
});
let multibuffer = cx.build_model(|cx| MultiBuffer::singleton(guest_buffer.clone(), cx));
let multibuffer = cx.new_model(|cx| MultiBuffer::singleton(guest_buffer.clone(), cx));
let snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(snapshot.text(), "a");
@ -4203,10 +4202,10 @@ mod tests {
#[gpui::test]
fn test_excerpt_boundaries_and_clipping(cx: &mut AppContext) {
let buffer_1 =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
let buffer_2 =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'g')));
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'g')));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let events = Arc::new(RwLock::new(Vec::<Event>::new()));
multibuffer.update(cx, |_, cx| {
@ -4439,12 +4438,12 @@ mod tests {
#[gpui::test]
fn test_excerpt_events(cx: &mut AppContext) {
let buffer_1 =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'a')));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'a')));
let buffer_2 =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'm')));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'm')));
let leader_multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let follower_multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let leader_multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let follower_multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let follower_edit_event_count = Arc::new(RwLock::new(0));
follower_multibuffer.update(cx, |_, cx| {
@ -4547,8 +4546,8 @@ mod tests {
#[gpui::test]
fn test_push_excerpts_with_context_lines(cx: &mut AppContext) {
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
multibuffer.push_excerpts_with_context_lines(
buffer.clone(),
@ -4584,8 +4583,8 @@ mod tests {
#[gpui::test]
async fn test_stream_excerpts_with_context_lines(cx: &mut TestAppContext) {
let buffer =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
let snapshot = buffer.read(cx);
let ranges = vec![
@ -4620,7 +4619,7 @@ mod tests {
#[gpui::test]
fn test_empty_multibuffer(cx: &mut AppContext) {
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(snapshot.text(), "");
@ -4630,8 +4629,8 @@ mod tests {
#[gpui::test]
fn test_singleton_multibuffer_anchors(cx: &mut AppContext) {
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let multibuffer = cx.build_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let multibuffer = cx.new_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
let old_snapshot = multibuffer.read(cx).snapshot(cx);
buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, "X")], None, cx);
@ -4650,9 +4649,9 @@ mod tests {
#[gpui::test]
fn test_multibuffer_anchors(cx: &mut AppContext) {
let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "efghi"));
let multibuffer = cx.build_model(|cx| {
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "efghi"));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer_1.clone(),
@ -4708,10 +4707,10 @@ mod tests {
#[gpui::test]
fn test_resolving_anchors_after_replacing_their_excerpts(cx: &mut AppContext) {
let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
let buffer_2 =
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "ABCDEFGHIJKLMNOP"));
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "ABCDEFGHIJKLMNOP"));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
// Create an insertion id in buffer 1 that doesn't exist in buffer 2.
// Add an excerpt from buffer 1 that spans this new insertion.
@ -4845,7 +4844,7 @@ mod tests {
.unwrap_or(10);
let mut buffers: Vec<Model<Buffer>> = Vec::new();
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let mut excerpt_ids = Vec::<ExcerptId>::new();
let mut expected_excerpts = Vec::<(Model<Buffer>, Range<text::Anchor>)>::new();
let mut anchors = Vec::new();
@ -4922,7 +4921,7 @@ mod tests {
.take(10)
.collect::<String>();
buffers.push(
cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text)),
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text)),
);
buffers.last().unwrap()
} else {
@ -5265,9 +5264,9 @@ mod tests {
let test_settings = SettingsStore::test(cx);
cx.set_global(test_settings);
let buffer_1 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "1234"));
let buffer_2 = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "5678"));
let multibuffer = cx.build_model(|_| MultiBuffer::new(0));
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "1234"));
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "5678"));
let multibuffer = cx.new_model(|_| MultiBuffer::new(0));
let group_interval = multibuffer.read(cx).history.group_interval;
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.push_excerpts(

View file

@ -11,7 +11,7 @@ use time::OffsetDateTime;
use util::ResultExt;
pub fn init(client: Arc<Client>, user_store: Model<UserStore>, cx: &mut AppContext) {
let notification_store = cx.build_model(|cx| NotificationStore::new(client, user_store, cx));
let notification_store = cx.new_model(|cx| NotificationStore::new(client, user_store, cx));
cx.set_global(notification_store);
}

View file

@ -4,7 +4,7 @@ use editor::{
};
use fuzzy::StringMatch;
use gpui::{
actions, div, rems, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
actions, div, rems, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
FontStyle, FontWeight, HighlightStyle, ParentElement, Point, Render, Styled, StyledText, Task,
TextStyle, View, ViewContext, VisualContext, WeakView, WhiteSpace, WindowContext,
};
@ -57,9 +57,7 @@ impl EventEmitter<DismissEvent> for OutlineView {}
impl ModalView for OutlineView {}
impl Render for OutlineView {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
v_stack().w(rems(34.)).child(self.picker.clone())
}
}
@ -82,7 +80,7 @@ impl OutlineView {
cx: &mut ViewContext<Self>,
) -> OutlineView {
let delegate = OutlineViewDelegate::new(cx.view().downgrade(), outline, editor, cx);
let picker = cx.build_view(|cx| Picker::new(delegate, cx));
let picker = cx.new_view(|cx| Picker::new(delegate, cx));
OutlineView { picker }
}
}

View file

@ -1,8 +1,8 @@
use editor::Editor;
use gpui::{
div, prelude::*, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
FocusHandle, FocusableView, Length, MouseButton, MouseDownEvent, Render, Task,
UniformListScrollHandle, View, ViewContext, WindowContext,
div, prelude::*, uniform_list, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
FocusableView, Length, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle,
View, ViewContext, WindowContext,
};
use std::{cmp, sync::Arc};
use ui::{prelude::*, v_stack, Color, Divider, Label, ListItem, ListItemSpacing, ListSeparator};
@ -59,7 +59,7 @@ impl<D: PickerDelegate> FocusableView for Picker<D> {
impl<D: PickerDelegate> Picker<D> {
pub fn new(delegate: D, cx: &mut ViewContext<Self>) -> Self {
let editor = cx.build_view(|cx| {
let editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text(delegate.placeholder_text(), cx);
editor
@ -228,9 +228,7 @@ impl<D: PickerDelegate> EventEmitter<DismissEvent> for Picker<D> {}
impl<D: PickerDelegate> ModalView for Picker<D> {}
impl<D: PickerDelegate> Render for Picker<D> {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let picker_editor = h_stack()
.overflow_hidden()
.flex_none()

View file

@ -636,7 +636,7 @@ impl Project {
fs: Arc<dyn Fs>,
cx: &mut AppContext,
) -> Model<Self> {
cx.build_model(|cx: &mut ModelContext<Self>| {
cx.new_model(|cx: &mut ModelContext<Self>| {
let (tx, rx) = mpsc::unbounded();
cx.spawn(move |this, cx| Self::send_buffer_ordered_messages(this, rx, cx))
.detach();
@ -712,7 +712,7 @@ impl Project {
project_id: remote_id,
})
.await?;
let this = cx.build_model(|cx| {
let this = cx.new_model(|cx| {
let replica_id = response.payload.replica_id as ReplicaId;
let mut worktrees = Vec::new();
@ -868,7 +868,7 @@ impl Project {
languages.set_executor(cx.executor());
let http_client = util::http::FakeHttpClient::with_404_response();
let client = cx.update(|cx| client::Client::new(http_client.clone(), cx));
let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let project = cx.update(|cx| {
Project::local(
client,
@ -1690,7 +1690,7 @@ impl Project {
return Err(anyhow!("creating buffers as a guest is not supported yet"));
}
let id = post_inc(&mut self.next_buffer_id);
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(self.replica_id(), id, text)
.with_language(language.unwrap_or_else(|| language::PLAIN_TEXT.clone()), cx)
});
@ -7193,7 +7193,7 @@ impl Project {
}
let buffer_id = state.id;
let buffer = cx.build_model(|_| {
let buffer = cx.new_model(|_| {
Buffer::from_proto(this.replica_id(), state, buffer_file).unwrap()
});
this.incomplete_remote_buffers

View file

@ -39,7 +39,7 @@ impl Project {
window,
)
.map(|builder| {
let terminal_handle = cx.build_model(|cx| builder.subscribe(cx));
let terminal_handle = cx.new_model(|cx| builder.subscribe(cx));
self.terminals
.local_handles

View file

@ -312,7 +312,7 @@ impl Worktree {
let closure_fs = Arc::clone(&fs);
let closure_next_entry_id = Arc::clone(&next_entry_id);
let closure_abs_path = abs_path.to_path_buf();
cx.build_model(move |cx: &mut ModelContext<Worktree>| {
cx.new_model(move |cx: &mut ModelContext<Worktree>| {
cx.observe_global::<SettingsStore>(move |this, cx| {
if let Self::Local(this) = this {
let new_file_scan_exclusions =
@ -415,7 +415,7 @@ impl Worktree {
client: Arc<Client>,
cx: &mut AppContext,
) -> Model<Self> {
cx.build_model(|cx: &mut ModelContext<Self>| {
cx.new_model(|cx: &mut ModelContext<Self>| {
let snapshot = Snapshot {
id: WorktreeId(worktree.id as usize),
abs_path: Arc::from(PathBuf::from(worktree.abs_path)),
@ -682,7 +682,7 @@ impl LocalWorktree {
.background_executor()
.spawn(async move { text::Buffer::new(0, id, contents) })
.await;
cx.build_model(|_| Buffer::build(text_buffer, diff_base, Some(Arc::new(file))))
cx.new_model(|_| Buffer::build(text_buffer, diff_base, Some(Arc::new(file))))
})
}

View file

@ -9,10 +9,10 @@ use file_associations::FileAssociations;
use anyhow::{anyhow, Result};
use gpui::{
actions, div, overlay, px, uniform_list, Action, AppContext, AssetSource, AsyncWindowContext,
ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
InteractiveElement, KeyContext, Model, MouseButton, MouseDownEvent, ParentElement, Pixels,
Point, PromptLevel, Render, Stateful, Styled, Subscription, Task, UniformListScrollHandle,
View, ViewContext, VisualContext as _, WeakView, WindowContext,
ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, InteractiveElement,
KeyContext, Model, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel,
Render, Stateful, Styled, Subscription, Task, UniformListScrollHandle, View, ViewContext,
VisualContext as _, WeakView, WindowContext,
};
use menu::{Confirm, SelectNext, SelectPrev};
use project::{
@ -168,7 +168,7 @@ struct DraggedProjectEntryView {
impl ProjectPanel {
fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
let project = workspace.project().clone();
let project_panel = cx.build_view(|cx: &mut ViewContext<Self>| {
let project_panel = cx.new_view(|cx: &mut ViewContext<Self>| {
cx.observe(&project, |this, _, cx| {
this.update_visible_entries(None, cx);
cx.notify();
@ -200,7 +200,7 @@ impl ProjectPanel {
})
.detach();
let filename_editor = cx.build_view(|cx| Editor::single_line(cx));
let filename_editor = cx.new_view(|cx| Editor::single_line(cx));
cx.subscribe(&filename_editor, |this, _, event, cx| match event {
editor::EditorEvent::BufferEdited
@ -1384,7 +1384,7 @@ impl ProjectPanel {
div()
.id(entry_id.to_proto() as usize)
.on_drag(entry_id, move |entry_id, cx| {
cx.build_view(|_| DraggedProjectEntryView {
cx.new_view(|_| DraggedProjectEntryView {
details: details.clone(),
width,
entry_id: *entry_id,
@ -1480,9 +1480,7 @@ impl ProjectPanel {
}
impl Render for ProjectPanel {
type Element = Focusable<Stateful<Div>>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
let has_worktree = self.visible_entries.len() != 0;
if has_worktree {
@ -1548,9 +1546,7 @@ impl Render for ProjectPanel {
}
impl Render for DraggedProjectEntryView {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let settings = ProjectPanelSettings::get_global(cx);
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
h_stack()

View file

@ -340,7 +340,7 @@ mod tests {
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project.clone(), cx));
// Create the project symbols view.
let symbols = cx.build_view(|cx| {
let symbols = cx.new_view(|cx| {
Picker::new(
ProjectSymbolsDelegate::new(workspace.downgrade(), project.clone()),
cx,

View file

@ -2,8 +2,8 @@ use assistant::{AssistantPanel, InlineAssist};
use editor::Editor;
use gpui::{
Action, ClickEvent, Div, ElementId, EventEmitter, InteractiveElement, ParentElement, Render,
Stateful, Styled, Subscription, View, ViewContext, WeakView,
Action, ClickEvent, ElementId, EventEmitter, InteractiveElement, ParentElement, Render, Styled,
Subscription, View, ViewContext, WeakView,
};
use search::{buffer_search, BufferSearchBar};
use ui::{prelude::*, ButtonSize, ButtonStyle, Icon, IconButton, IconSize, Tooltip};
@ -36,9 +36,7 @@ impl QuickActionBar {
}
impl Render for QuickActionBar {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let Some(editor) = self.active_editor() else {
return div().id("empty quick action bar");
};
@ -138,9 +136,9 @@ impl QuickActionBarButton {
}
impl RenderOnce for QuickActionBarButton {
type Rendered = IconButton;
type Output = IconButton;
fn render(self, _: &mut WindowContext) -> Self::Rendered {
fn render(self, _: &mut WindowContext) -> Self::Output {
let tooltip = self.tooltip.clone();
let action = self.action.boxed_clone();

View file

@ -43,9 +43,9 @@ impl HighlightedText {
}
impl RenderOnce for HighlightedText {
type Rendered = HighlightedLabel;
type Output = HighlightedLabel;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
HighlightedLabel::new(self.text, self.highlight_positions)
}
}

View file

@ -3,8 +3,8 @@ mod projects;
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Subscription,
Task, View, ViewContext, WeakView,
AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Result, Subscription, Task,
View, ViewContext, WeakView,
};
use highlighted_workspace_location::HighlightedWorkspaceLocation;
use ordered_float::OrderedFloat;
@ -29,12 +29,8 @@ pub struct RecentProjects {
impl ModalView for RecentProjects {}
impl RecentProjects {
pub fn new(
delegate: RecentProjectsDelegate,
rem_width: f32,
cx: &mut ViewContext<Self>,
) -> Self {
let picker = cx.build_view(|cx| Picker::new(delegate, cx));
fn new(delegate: RecentProjectsDelegate, rem_width: f32, cx: &mut ViewContext<Self>) -> Self {
let picker = cx.new_view(|cx| Picker::new(delegate, cx));
let _subscription = cx.subscribe(&picker, |_, _, _, cx| cx.emit(DismissEvent));
// We do not want to block the UI on a potentially lenghty call to DB, so we're gonna swap
// out workspace locations once the future runs to completion.
@ -94,7 +90,7 @@ impl RecentProjects {
}))
}
pub fn open_popover(workspace: WeakView<Workspace>, cx: &mut WindowContext<'_>) -> View<Self> {
cx.build_view(|cx| Self::new(RecentProjectsDelegate::new(workspace, false), 20., cx))
cx.new_view(|cx| Self::new(RecentProjectsDelegate::new(workspace, false), 20., cx))
}
}
@ -107,9 +103,7 @@ impl FocusableView for RecentProjects {
}
impl Render for RecentProjects {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
v_stack()
.w(rems(self.rem_width))
.child(self.picker.clone())

View file

@ -10,7 +10,7 @@ use collections::HashMap;
use editor::{Editor, EditorElement, EditorStyle};
use futures::channel::oneshot;
use gpui::{
actions, div, impl_actions, Action, AppContext, ClickEvent, Div, EventEmitter, FocusableView,
actions, div, impl_actions, Action, AppContext, ClickEvent, EventEmitter, FocusableView,
FontStyle, FontWeight, InteractiveElement as _, IntoElement, KeyContext, ParentElement as _,
Render, Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext as _,
WhiteSpace, WindowContext,
@ -101,9 +101,7 @@ impl BufferSearchBar {
impl EventEmitter<Event> for BufferSearchBar {}
impl EventEmitter<workspace::ToolbarItemEvent> for BufferSearchBar {}
impl Render for BufferSearchBar {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
if self.dismissed {
return div();
}
@ -183,7 +181,11 @@ impl Render for BufferSearchBar {
if in_replace {
key_context.add("in_replace");
}
let editor_border = if self.query_contains_error {
Color::Error.color(cx)
} else {
cx.theme().colors().border
};
h_stack()
.w_full()
.gap_2()
@ -219,7 +221,7 @@ impl Render for BufferSearchBar {
.py_1()
.gap_2()
.border_1()
.border_color(cx.theme().colors().border)
.border_color(editor_border)
.rounded_lg()
.child(IconElement::new(Icon::MagnifyingGlass))
.child(self.render_text_input(&self.query_editor, cx))
@ -432,7 +434,7 @@ impl BufferSearchBar {
});
return;
}
let view = cx.build_view(|cx| BufferSearchBar::new(cx));
let view = cx.new_view(|cx| BufferSearchBar::new(cx));
this.add_item(view.clone(), cx);
view.update(cx, |this, cx| this.deploy(deploy, cx));
cx.notify();
@ -504,10 +506,10 @@ impl BufferSearchBar {
});
}
pub fn new(cx: &mut ViewContext<Self>) -> Self {
let query_editor = cx.build_view(|cx| Editor::single_line(cx));
let query_editor = cx.new_view(|cx| Editor::single_line(cx));
cx.subscribe(&query_editor, Self::on_query_editor_event)
.detach();
let replacement_editor = cx.build_view(|cx| Editor::single_line(cx));
let replacement_editor = cx.new_view(|cx| Editor::single_line(cx));
cx.subscribe(&replacement_editor, Self::on_query_editor_event)
.detach();
Self {
@ -854,6 +856,7 @@ impl BufferSearchBar {
Ok(query) => query.with_replacement(self.replacement(cx)),
Err(_) => {
self.query_contains_error = true;
self.active_match_index = None;
cx.notify();
return done_rx;
}
@ -870,6 +873,7 @@ impl BufferSearchBar {
Ok(query) => query.with_replacement(self.replacement(cx)),
Err(_) => {
self.query_contains_error = true;
self.active_match_index = None;
cx.notify();
return done_rx;
}
@ -1040,7 +1044,7 @@ mod tests {
&mut VisualTestContext<'_>,
) {
init_globals(cx);
let buffer = cx.build_model(|cx| {
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
cx.entity_id().as_u64(),
@ -1054,9 +1058,9 @@ mod tests {
)
});
let (_, cx) = cx.add_window_view(|_| EmptyView {});
let editor = cx.build_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
let editor = cx.new_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
let search_bar = cx.build_view(|cx| {
let search_bar = cx.new_view(|cx| {
let mut search_bar = BufferSearchBar::new(cx);
search_bar.set_active_pane_item(Some(&editor), cx);
search_bar.show(cx);
@ -1401,7 +1405,7 @@ mod tests {
expected_query_matches_count > 1,
"Should pick a query with multiple results"
);
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
let window = cx.add_window(|_| EmptyView {});
let editor = window.build_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx));
@ -1598,12 +1602,12 @@ mod tests {
for "find" or "find and replace" operations on strings, or for input validation.
"#
.unindent();
let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
let (_, cx) = cx.add_window_view(|_| EmptyView {});
let editor = cx.build_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
let editor = cx.new_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
let search_bar = cx.build_view(|cx| {
let search_bar = cx.new_view(|cx| {
let mut search_bar = BufferSearchBar::new(cx);
search_bar.set_active_pane_item(Some(&editor), cx);
search_bar.show(cx);

View file

@ -12,10 +12,10 @@ use editor::{
};
use editor::{EditorElement, EditorStyle};
use gpui::{
actions, div, AnyElement, AnyView, AppContext, Context as _, Div, Element, EntityId,
EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, InteractiveElement,
IntoElement, KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString,
Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView,
actions, div, AnyElement, AnyView, AppContext, Context as _, Element, EntityId, EventEmitter,
FocusHandle, FocusableView, FontStyle, FontWeight, Hsla, InteractiveElement, IntoElement,
KeyContext, Model, ModelContext, ParentElement, PromptLevel, Render, SharedString, Styled,
Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakModel, WeakView,
WhiteSpace, WindowContext,
};
use menu::Confirm;
@ -134,7 +134,7 @@ impl ProjectSearch {
let replica_id = project.read(cx).replica_id();
Self {
project,
excerpts: cx.build_model(|_| MultiBuffer::new(replica_id)),
excerpts: cx.new_model(|_| MultiBuffer::new(replica_id)),
pending_search: Default::default(),
match_ranges: Default::default(),
active_query: None,
@ -145,11 +145,11 @@ impl ProjectSearch {
}
fn clone(&self, cx: &mut ModelContext<Self>) -> Model<Self> {
cx.build_model(|cx| Self {
cx.new_model(|cx| Self {
project: self.project.clone(),
excerpts: self
.excerpts
.update(cx, |excerpts, cx| cx.build_model(|cx| excerpts.clone(cx))),
.update(cx, |excerpts, cx| cx.new_model(|cx| excerpts.clone(cx))),
pending_search: Default::default(),
match_ranges: self.match_ranges.clone(),
active_query: self.active_query.clone(),
@ -279,9 +279,7 @@ pub enum ViewEvent {
impl EventEmitter<ViewEvent> for ProjectSearchView {}
impl Render for ProjectSearchView {
type Element = AnyElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
if self.has_matches() {
div()
.flex_1()
@ -506,7 +504,7 @@ impl Item for ProjectSearchView {
Self: Sized,
{
let model = self.model.update(cx, |model, cx| model.clone(cx));
Some(cx.build_view(|cx| Self::new(model, cx, None)))
Some(cx.new_view(|cx| Self::new(model, cx, None)))
}
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
@ -807,7 +805,7 @@ impl ProjectSearchView {
}
subscriptions.push(cx.observe(&model, |this, _, cx| this.model_changed(cx)));
let query_editor = cx.build_view(|cx| {
let query_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Text search all files", cx);
editor.set_text(query_text, cx);
@ -819,7 +817,7 @@ impl ProjectSearchView {
cx.emit(ViewEvent::EditorEvent(event.clone()))
}),
);
let replacement_editor = cx.build_view(|cx| {
let replacement_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Replace in project..", cx);
if let Some(text) = replacement_text {
@ -827,7 +825,7 @@ impl ProjectSearchView {
}
editor
});
let results_editor = cx.build_view(|cx| {
let results_editor = cx.new_view(|cx| {
let mut editor = Editor::for_multibuffer(excerpts, Some(project.clone()), cx);
editor.set_searchable(false);
editor
@ -844,7 +842,7 @@ impl ProjectSearchView {
}),
);
let included_files_editor = cx.build_view(|cx| {
let included_files_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Include: crates/**/*.toml", cx);
@ -857,7 +855,7 @@ impl ProjectSearchView {
}),
);
let excluded_files_editor = cx.build_view(|cx| {
let excluded_files_editor = cx.new_view(|cx| {
let mut editor = Editor::single_line(cx);
editor.set_placeholder_text("Exclude: vendor/*, *.lock", cx);
@ -931,8 +929,8 @@ impl ProjectSearchView {
return;
};
let model = cx.build_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
let search = cx.build_view(|cx| ProjectSearchView::new(model, cx, None));
let model = cx.new_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
let search = cx.new_view(|cx| ProjectSearchView::new(model, cx, None));
workspace.add_item(Box::new(search.clone()), cx);
search.update(cx, |search, cx| {
search
@ -975,8 +973,8 @@ impl ProjectSearchView {
None
};
let model = cx.build_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
let search = cx.build_view(|cx| ProjectSearchView::new(model, cx, settings));
let model = cx.new_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
let search = cx.new_view(|cx| ProjectSearchView::new(model, cx, settings));
workspace.add_item(Box::new(search.clone()), cx);
@ -1009,33 +1007,46 @@ impl ProjectSearchView {
}
fn build_search_query(&mut self, cx: &mut ViewContext<Self>) -> Option<SearchQuery> {
// Do not bail early in this function, as we want to fill out `self.panels_with_errors`.
let text = self.query_editor.read(cx).text(cx);
let included_files =
match Self::parse_path_matches(&self.included_files_editor.read(cx).text(cx)) {
Ok(included_files) => {
self.panels_with_errors.remove(&InputPanel::Include);
let should_unmark_error = self.panels_with_errors.remove(&InputPanel::Include);
if should_unmark_error {
cx.notify();
}
included_files
}
Err(_e) => {
self.panels_with_errors.insert(InputPanel::Include);
cx.notify();
return None;
let should_mark_error = self.panels_with_errors.insert(InputPanel::Include);
if should_mark_error {
cx.notify();
}
vec![]
}
};
let excluded_files =
match Self::parse_path_matches(&self.excluded_files_editor.read(cx).text(cx)) {
Ok(excluded_files) => {
self.panels_with_errors.remove(&InputPanel::Exclude);
let should_unmark_error = self.panels_with_errors.remove(&InputPanel::Exclude);
if should_unmark_error {
cx.notify();
}
excluded_files
}
Err(_e) => {
self.panels_with_errors.insert(InputPanel::Exclude);
cx.notify();
return None;
let should_mark_error = self.panels_with_errors.insert(InputPanel::Exclude);
if should_mark_error {
cx.notify();
}
vec![]
}
};
let current_mode = self.current_mode;
match current_mode {
let query = match current_mode {
SearchMode::Regex => {
match SearchQuery::regex(
text,
@ -1046,12 +1057,20 @@ impl ProjectSearchView {
excluded_files,
) {
Ok(query) => {
self.panels_with_errors.remove(&InputPanel::Query);
let should_unmark_error =
self.panels_with_errors.remove(&InputPanel::Query);
if should_unmark_error {
cx.notify();
}
Some(query)
}
Err(_e) => {
self.panels_with_errors.insert(InputPanel::Query);
cx.notify();
let should_mark_error = self.panels_with_errors.insert(InputPanel::Query);
if should_mark_error {
cx.notify();
}
None
}
}
@ -1065,16 +1084,27 @@ impl ProjectSearchView {
excluded_files,
) {
Ok(query) => {
self.panels_with_errors.remove(&InputPanel::Query);
let should_unmark_error = self.panels_with_errors.remove(&InputPanel::Query);
if should_unmark_error {
cx.notify();
}
Some(query)
}
Err(_e) => {
self.panels_with_errors.insert(InputPanel::Query);
cx.notify();
let should_mark_error = self.panels_with_errors.insert(InputPanel::Query);
if should_mark_error {
cx.notify();
}
None
}
},
};
if !self.panels_with_errors.is_empty() {
return None;
}
query
}
fn parse_path_matches(text: &str) -> anyhow::Result<Vec<PathMatcher>> {
@ -1187,6 +1217,21 @@ impl ProjectSearchView {
SearchMode::Semantic => "\nSimply explain the code you are looking to find. ex. 'prompt user for permissions to index their project'".into()
}
}
fn border_color_for(&self, panel: InputPanel, cx: &WindowContext) -> Hsla {
if self.panels_with_errors.contains(&panel) {
Color::Error.color(cx)
} else {
cx.theme().colors().border
}
}
fn move_focus_to_results(&mut self, cx: &mut ViewContext<Self>) {
if !self.results_editor.focus_handle(cx).is_focused(cx)
&& !self.model.read(cx).match_ranges.is_empty()
{
cx.stop_propagation();
return self.focus_results_editor(cx);
}
}
}
impl Default for ProjectSearchBar {
@ -1248,13 +1293,13 @@ impl ProjectSearchBar {
new_query
});
if let Some(new_query) = new_query {
let model = cx.build_model(|cx| {
let model = cx.new_model(|cx| {
let mut model = ProjectSearch::new(workspace.project().clone(), cx);
model.search(new_query, cx);
model
});
workspace.add_item(
Box::new(cx.build_view(|cx| ProjectSearchView::new(model, cx, None))),
Box::new(cx.new_view(|cx| ProjectSearchView::new(model, cx, None))),
cx,
);
}
@ -1361,6 +1406,15 @@ impl ProjectSearchBar {
}
}
fn move_focus_to_results(&self, cx: &mut ViewContext<Self>) {
if let Some(search_view) = self.active_project_search.as_ref() {
search_view.update(cx, |search_view, cx| {
search_view.move_focus_to_results(cx);
});
cx.notify();
}
}
fn activate_search_mode(&self, mode: SearchMode, cx: &mut ViewContext<Self>) {
// Update Current Mode
if let Some(search_view) = self.active_project_search.as_ref() {
@ -1494,9 +1548,7 @@ impl ProjectSearchBar {
}
impl Render for ProjectSearchBar {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let Some(search) = self.active_project_search.clone() else {
return div();
};
@ -1511,6 +1563,7 @@ impl Render for ProjectSearchBar {
}
let search = search.read(cx);
let semantic_is_available = SemanticIndex::enabled(cx);
let query_column = v_stack().child(
h_stack()
.min_w(rems(512. / 16.))
@ -1519,7 +1572,7 @@ impl Render for ProjectSearchBar {
.gap_2()
.bg(cx.theme().colors().editor_background)
.border_1()
.border_color(cx.theme().colors().border)
.border_color(search.border_color_for(InputPanel::Query, cx))
.rounded_lg()
.on_action(cx.listener(|this, action, cx| this.confirm(action, cx)))
.on_action(cx.listener(|this, action, cx| this.previous_history_query(action, cx)))
@ -1718,6 +1771,7 @@ impl Render for ProjectSearchBar {
.key_context(key_context)
.flex_grow()
.gap_2()
.on_action(cx.listener(|this, _: &ToggleFocus, cx| this.move_focus_to_results(cx)))
.on_action(cx.listener(|this, _: &ToggleFilters, cx| {
this.toggle_filters(cx);
}))
@ -1793,7 +1847,7 @@ impl Render for ProjectSearchBar {
.px_2()
.py_1()
.border_1()
.border_color(cx.theme().colors().border)
.border_color(search.border_color_for(InputPanel::Include, cx))
.rounded_lg()
.child(self.render_text_input(&search.included_files_editor, cx))
.when(search.current_mode != SearchMode::Semantic, |this| {
@ -1819,7 +1873,7 @@ impl Render for ProjectSearchBar {
.px_2()
.py_1()
.border_1()
.border_color(cx.theme().colors().border)
.border_color(search.border_color_for(InputPanel::Exclude, cx))
.rounded_lg()
.child(self.render_text_input(&search.excluded_files_editor, cx)),
),
@ -1890,7 +1944,7 @@ pub mod tests {
)
.await;
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
let search = cx.build_model(|cx| ProjectSearch::new(project, cx));
let search = cx.new_model(|cx| ProjectSearch::new(project, cx));
let search_view = cx.add_window(|cx| ProjectSearchView::new(search.clone(), cx, None));
search_view

View file

@ -341,7 +341,7 @@ impl SemanticIndex {
t0.elapsed().as_millis()
);
cx.build_model(|cx| {
cx.new_model(|cx| {
let t0 = Instant::now();
let embedding_queue =
EmbeddingQueue::new(embedding_provider.clone(), cx.background_executor().clone());

View file

@ -74,9 +74,9 @@ impl ParentElement for StoryContainer {
}
impl RenderOnce for StoryContainer {
type Rendered = Stateful<Div>;
type Output = Stateful<Div>;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div()
.size_full()
.flex()
@ -294,9 +294,9 @@ impl StoryItem {
}
impl RenderOnce for StoryItem {
type Rendered = Div;
type Output = Div;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div()
.my_2()
.flex()
@ -358,9 +358,9 @@ impl StorySection {
}
impl RenderOnce for StorySection {
type Rendered = Div;
type Output = Div;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with(
self.children.into_iter(),
|| Story::divider().into_any_element(),

View file

@ -1,7 +1,7 @@
use editor::Editor;
use gpui::{
div, white, Div, KeyBinding, ParentElement, Render, Styled, View, ViewContext, VisualContext,
WindowContext,
div, white, Element, KeyBinding, ParentElement, Render, Styled, View, ViewContext,
VisualContext, WindowContext,
};
pub struct AutoHeightEditorStory {
@ -11,8 +11,8 @@ pub struct AutoHeightEditorStory {
impl AutoHeightEditorStory {
pub fn new(cx: &mut WindowContext) -> View<Self> {
cx.bind_keys([KeyBinding::new("enter", editor::Newline, Some("Editor"))]);
cx.build_view(|cx| Self {
editor: cx.build_view(|cx| {
cx.new_view(|cx| Self {
editor: cx.new_view(|cx| {
let mut editor = Editor::auto_height(3, cx);
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
editor
@ -22,9 +22,7 @@ impl AutoHeightEditorStory {
}
impl Render for AutoHeightEditorStory {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
div()
.size_full()
.bg(white())

View file

@ -5,9 +5,7 @@ use ui::prelude::*;
pub struct CursorStory;
impl Render for CursorStory {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
let all_cursors: [(&str, Box<dyn Fn(Stateful<Div>) -> Stateful<Div>>); 19] = [
(
"cursor_default",

View file

@ -1,6 +1,5 @@
use gpui::{
actions, div, prelude::*, Div, FocusHandle, Focusable, KeyBinding, Render, Stateful,
Subscription, View, WindowContext,
actions, div, prelude::*, FocusHandle, KeyBinding, Render, Subscription, View, WindowContext,
};
use ui::prelude::*;
@ -21,7 +20,7 @@ impl FocusStory {
KeyBinding::new("cmd-c", ActionC, None),
]);
cx.build_view(move |cx| {
cx.new_view(move |cx| {
let parent_focus = cx.focus_handle();
let child_1_focus = cx.focus_handle();
let child_2_focus = cx.focus_handle();
@ -57,9 +56,7 @@ impl FocusStory {
}
impl Render for FocusStory {
type Element = Focusable<Stateful<Div>>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
let theme = cx.theme();
let color_1 = theme.status().created;
let color_2 = theme.status().modified;

View file

@ -1,4 +1,4 @@
use gpui::{prelude::*, Div, Render, Stateful, View};
use gpui::{prelude::*, Render, View};
use story::Story;
use strum::IntoEnumIterator;
use ui::prelude::*;
@ -9,14 +9,12 @@ pub struct KitchenSinkStory;
impl KitchenSinkStory {
pub fn view(cx: &mut WindowContext) -> View<Self> {
cx.build_view(|_cx| Self)
cx.new_view(|_cx| Self)
}
}
impl Render for KitchenSinkStory {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element {
let component_stories = ComponentStory::iter()
.map(|selector| selector.story(cx))
.collect::<Vec<_>>();

View file

@ -1,4 +1,4 @@
use gpui::{Div, Render};
use gpui::Render;
use story::Story;
use ui::prelude::*;
@ -6,9 +6,7 @@ use ui::prelude::*;
pub struct OverflowScrollStory;
impl Render for OverflowScrollStory {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl Element {
Story::container()
.child(Story::title("Overflow Scroll"))
.child(Story::label("`overflow_x_scroll`"))

View file

@ -1,7 +1,5 @@
use fuzzy::StringMatchCandidate;
use gpui::{
div, prelude::*, Div, KeyBinding, Render, SharedString, Styled, Task, View, WindowContext,
};
use gpui::{div, prelude::*, KeyBinding, Render, SharedString, Styled, Task, View, WindowContext};
use picker::{Picker, PickerDelegate};
use std::sync::Arc;
use ui::{prelude::*, ListItemSpacing};
@ -118,7 +116,7 @@ impl PickerDelegate for Delegate {
impl PickerStory {
pub fn new(cx: &mut WindowContext) -> View<Self> {
cx.build_view(|cx| {
cx.new_view(|cx| {
cx.bind_keys([
KeyBinding::new("up", menu::SelectPrev, Some("picker")),
KeyBinding::new("pageup", menu::SelectFirst, Some("picker")),
@ -138,7 +136,7 @@ impl PickerStory {
]);
PickerStory {
picker: cx.build_view(|cx| {
picker: cx.new_view(|cx| {
let mut delegate = Delegate::new(&[
"Baguette (France)",
"Baklava (Turkey)",
@ -202,9 +200,7 @@ impl PickerStory {
}
impl Render for PickerStory {
type Element = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
div()
.bg(cx.theme().styles.colors.background)
.size_full()

View file

@ -1,4 +1,4 @@
use gpui::{div, prelude::*, px, Div, Render, SharedString, Stateful, Styled, View, WindowContext};
use gpui::{div, prelude::*, px, Render, SharedString, Styled, View, WindowContext};
use ui::prelude::*;
use ui::Tooltip;
@ -6,14 +6,12 @@ pub struct ScrollStory;
impl ScrollStory {
pub fn view(cx: &mut WindowContext) -> View<ScrollStory> {
cx.build_view(|_cx| ScrollStory)
cx.new_view(|_cx| ScrollStory)
}
}
impl Render for ScrollStory {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl Element {
let theme = cx.theme();
let color_1 = theme.status().created;
let color_2 = theme.status().modified;

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