Auto-fix clippy::collapsible_if violations (#36428)

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-08-19 15:27:24 +02:00 committed by GitHub
parent 9e8ec72bd5
commit 8f567383e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
281 changed files with 6628 additions and 7089 deletions

View file

@ -830,6 +830,7 @@ module_inception = { level = "deny" }
question_mark = { level = "deny" } question_mark = { level = "deny" }
redundant_closure = { level = "deny" } redundant_closure = { level = "deny" }
declare_interior_mutable_const = { level = "deny" } declare_interior_mutable_const = { level = "deny" }
collapsible_if = { level = "warn"}
needless_borrow = { level = "warn"} needless_borrow = { level = "warn"}
# Individual rules that have violations in the codebase: # Individual rules that have violations in the codebase:
type_complexity = "allow" type_complexity = "allow"

View file

@ -249,14 +249,13 @@ impl ToolCall {
} }
if let Some(raw_output) = raw_output { if let Some(raw_output) = raw_output {
if self.content.is_empty() { if self.content.is_empty()
if let Some(markdown) = markdown_for_raw_output(&raw_output, &language_registry, cx) && let Some(markdown) = markdown_for_raw_output(&raw_output, &language_registry, cx)
{ {
self.content self.content
.push(ToolCallContent::ContentBlock(ContentBlock::Markdown { .push(ToolCallContent::ContentBlock(ContentBlock::Markdown {
markdown, markdown,
})); }));
}
} }
self.raw_output = Some(raw_output); self.raw_output = Some(raw_output);
} }
@ -430,11 +429,11 @@ impl ContentBlock {
language_registry: &Arc<LanguageRegistry>, language_registry: &Arc<LanguageRegistry>,
cx: &mut App, cx: &mut App,
) { ) {
if matches!(self, ContentBlock::Empty) { if matches!(self, ContentBlock::Empty)
if let acp::ContentBlock::ResourceLink(resource_link) = block { && let acp::ContentBlock::ResourceLink(resource_link) = block
*self = ContentBlock::ResourceLink { resource_link }; {
return; *self = ContentBlock::ResourceLink { resource_link };
} return;
} }
let new_content = self.block_string_contents(block); let new_content = self.block_string_contents(block);

View file

@ -614,10 +614,10 @@ impl ActionLog {
false false
} }
}); });
if tracked_buffer.unreviewed_edits.is_empty() { if tracked_buffer.unreviewed_edits.is_empty()
if let TrackedBufferStatus::Created { .. } = &mut tracked_buffer.status { && let TrackedBufferStatus::Created { .. } = &mut tracked_buffer.status
tracked_buffer.status = TrackedBufferStatus::Modified; {
} tracked_buffer.status = TrackedBufferStatus::Modified;
} }
tracked_buffer.schedule_diff_update(ChangeAuthor::User, cx); tracked_buffer.schedule_diff_update(ChangeAuthor::User, cx);
} }

View file

@ -458,26 +458,24 @@ impl ActivityIndicator {
.map(|r| r.read(cx)) .map(|r| r.read(cx))
.and_then(Repository::current_job); .and_then(Repository::current_job);
// Show any long-running git command // Show any long-running git command
if let Some(job_info) = current_job { if let Some(job_info) = current_job
if Instant::now() - job_info.start >= GIT_OPERATION_DELAY { && Instant::now() - job_info.start >= GIT_OPERATION_DELAY
return Some(Content { {
icon: Some( return Some(Content {
Icon::new(IconName::ArrowCircle) icon: Some(
.size(IconSize::Small) Icon::new(IconName::ArrowCircle)
.with_animation( .size(IconSize::Small)
"arrow-circle", .with_animation(
Animation::new(Duration::from_secs(2)).repeat(), "arrow-circle",
|icon, delta| { Animation::new(Duration::from_secs(2)).repeat(),
icon.transform(Transformation::rotate(percentage(delta))) |icon, delta| icon.transform(Transformation::rotate(percentage(delta))),
}, )
) .into_any_element(),
.into_any_element(), ),
), message: job_info.message.into(),
message: job_info.message.into(), on_click: None,
on_click: None, tooltip_message: None,
tooltip_message: None, });
});
}
} }
// Show any language server installation info. // Show any language server installation info.
@ -740,21 +738,20 @@ impl ActivityIndicator {
if let Some(extension_store) = if let Some(extension_store) =
ExtensionStore::try_global(cx).map(|extension_store| extension_store.read(cx)) ExtensionStore::try_global(cx).map(|extension_store| extension_store.read(cx))
&& let Some(extension_id) = extension_store.outstanding_operations().keys().next()
{ {
if let Some(extension_id) = extension_store.outstanding_operations().keys().next() { return Some(Content {
return Some(Content { icon: Some(
icon: Some( Icon::new(IconName::Download)
Icon::new(IconName::Download) .size(IconSize::Small)
.size(IconSize::Small) .into_any_element(),
.into_any_element(), ),
), message: format!("Updating {extension_id} extension…"),
message: format!("Updating {extension_id} extension…"), on_click: Some(Arc::new(|this, window, cx| {
on_click: Some(Arc::new(|this, window, cx| { this.dismiss_error_message(&DismissErrorMessage, window, cx)
this.dismiss_error_message(&DismissErrorMessage, window, cx) })),
})), tooltip_message: None,
tooltip_message: None, });
});
}
} }
None None

View file

@ -201,24 +201,24 @@ impl FileContextHandle {
parse_status.changed().await.log_err(); parse_status.changed().await.log_err();
} }
if let Ok(snapshot) = buffer.read_with(cx, |buffer, _| buffer.snapshot()) { if let Ok(snapshot) = buffer.read_with(cx, |buffer, _| buffer.snapshot())
if let Some(outline) = snapshot.outline(None) { && let Some(outline) = snapshot.outline(None)
let items = outline {
.items let items = outline
.into_iter() .items
.map(|item| item.to_point(&snapshot)); .into_iter()
.map(|item| item.to_point(&snapshot));
if let Ok(outline_text) = if let Ok(outline_text) =
outline::render_outline(items, None, 0, usize::MAX).await outline::render_outline(items, None, 0, usize::MAX).await
{ {
let context = AgentContext::File(FileContext { let context = AgentContext::File(FileContext {
handle: self, handle: self,
full_path, full_path,
text: outline_text.into(), text: outline_text.into(),
is_outline: true, is_outline: true,
}); });
return Some((context, vec![buffer])); return Some((context, vec![buffer]));
}
} }
} }
} }

View file

@ -338,11 +338,9 @@ impl ContextStore {
image_task, image_task,
context_id: self.next_context_id.post_inc(), context_id: self.next_context_id.post_inc(),
}); });
if self.has_context(&context) { if self.has_context(&context) && remove_if_exists {
if remove_if_exists { self.remove_context(&context, cx);
self.remove_context(&context, cx); return None;
return None;
}
} }
self.insert_context(context.clone(), cx); self.insert_context(context.clone(), cx);

View file

@ -1967,11 +1967,9 @@ impl Thread {
if let Some(prev_message) = if let Some(prev_message) =
thread.messages.get(ix - 1) thread.messages.get(ix - 1)
{ && prev_message.role == Role::Assistant {
if prev_message.role == Role::Assistant {
break; break;
} }
}
} }
} }
@ -2476,13 +2474,13 @@ impl Thread {
.ok()?; .ok()?;
// Save thread so its summary can be reused later // Save thread so its summary can be reused later
if let Some(thread) = thread.upgrade() { if let Some(thread) = thread.upgrade()
if let Ok(Ok(save_task)) = cx.update(|cx| { && let Ok(Ok(save_task)) = cx.update(|cx| {
thread_store thread_store
.update(cx, |thread_store, cx| thread_store.save_thread(&thread, cx)) .update(cx, |thread_store, cx| thread_store.save_thread(&thread, cx))
}) { })
save_task.await.log_err(); {
} save_task.await.log_err();
} }
Some(()) Some(())
@ -2730,12 +2728,11 @@ impl Thread {
window: Option<AnyWindowHandle>, window: Option<AnyWindowHandle>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if self.all_tools_finished() { if self.all_tools_finished()
if let Some(ConfiguredModel { model, .. }) = self.configured_model.as_ref() { && let Some(ConfiguredModel { model, .. }) = self.configured_model.as_ref()
if !canceled { && !canceled
self.send_to_model(model.clone(), CompletionIntent::ToolResults, window, cx); {
} self.send_to_model(model.clone(), CompletionIntent::ToolResults, window, cx);
}
} }
cx.emit(ThreadEvent::ToolFinished { cx.emit(ThreadEvent::ToolFinished {
@ -2922,11 +2919,11 @@ impl Thread {
let buffer_store = project.read(app_cx).buffer_store(); let buffer_store = project.read(app_cx).buffer_store();
for buffer_handle in buffer_store.read(app_cx).buffers() { for buffer_handle in buffer_store.read(app_cx).buffers() {
let buffer = buffer_handle.read(app_cx); let buffer = buffer_handle.read(app_cx);
if buffer.is_dirty() { if buffer.is_dirty()
if let Some(file) = buffer.file() { && let Some(file) = buffer.file()
let path = file.path().to_string_lossy().to_string(); {
unsaved_buffers.push(path); let path = file.path().to_string_lossy().to_string();
} unsaved_buffers.push(path);
} }
} }
}) })
@ -3178,13 +3175,13 @@ impl Thread {
.model .model
.max_token_count_for_mode(self.completion_mode().into()); .max_token_count_for_mode(self.completion_mode().into());
if let Some(exceeded_error) = &self.exceeded_window_error { if let Some(exceeded_error) = &self.exceeded_window_error
if model.model.id() == exceeded_error.model_id { && model.model.id() == exceeded_error.model_id
return Some(TotalTokenUsage { {
total: exceeded_error.token_count, return Some(TotalTokenUsage {
max, total: exceeded_error.token_count,
}); max,
} });
} }
let total = self let total = self

View file

@ -581,33 +581,32 @@ impl ThreadStore {
return; return;
}; };
if protocol.capable(context_server::protocol::ServerCapability::Tools) { if protocol.capable(context_server::protocol::ServerCapability::Tools)
if let Some(response) = protocol && let Some(response) = protocol
.request::<context_server::types::requests::ListTools>(()) .request::<context_server::types::requests::ListTools>(())
.await .await
.log_err() .log_err()
{ {
let tool_ids = tool_working_set let tool_ids = tool_working_set
.update(cx, |tool_working_set, cx| { .update(cx, |tool_working_set, cx| {
tool_working_set.extend( tool_working_set.extend(
response.tools.into_iter().map(|tool| { response.tools.into_iter().map(|tool| {
Arc::new(ContextServerTool::new( Arc::new(ContextServerTool::new(
context_server_store.clone(), context_server_store.clone(),
server.id(), server.id(),
tool, tool,
)) as Arc<dyn Tool> )) as Arc<dyn Tool>
}), }),
cx, cx,
) )
}) })
.log_err(); .log_err();
if let Some(tool_ids) = tool_ids { if let Some(tool_ids) = tool_ids {
this.update(cx, |this, _| { this.update(cx, |this, _| {
this.context_server_tool_ids.insert(server_id, tool_ids); this.context_server_tool_ids.insert(server_id, tool_ids);
}) })
.log_err(); .log_err();
}
} }
} }
}) })
@ -697,13 +696,14 @@ impl SerializedThreadV0_1_0 {
let mut messages: Vec<SerializedMessage> = Vec::with_capacity(self.0.messages.len()); let mut messages: Vec<SerializedMessage> = Vec::with_capacity(self.0.messages.len());
for message in self.0.messages { for message in self.0.messages {
if message.role == Role::User && !message.tool_results.is_empty() { if message.role == Role::User
if let Some(last_message) = messages.last_mut() { && !message.tool_results.is_empty()
debug_assert!(last_message.role == Role::Assistant); && let Some(last_message) = messages.last_mut()
{
debug_assert!(last_message.role == Role::Assistant);
last_message.tool_results = message.tool_results; last_message.tool_results = message.tool_results;
continue; continue;
}
} }
messages.push(message); messages.push(message);

View file

@ -112,19 +112,13 @@ impl ToolUseState {
}, },
); );
if let Some(window) = &mut window { if let Some(window) = &mut window
if let Some(tool) = this.tools.read(cx).tool(tool_use, cx) { && let Some(tool) = this.tools.read(cx).tool(tool_use, cx)
if let Some(output) = tool_result.output.clone() { && let Some(output) = tool_result.output.clone()
if let Some(card) = tool.deserialize_card( && let Some(card) =
output, tool.deserialize_card(output, project.clone(), window, cx)
project.clone(), {
window, this.tool_result_cards.insert(tool_use_id, card);
cx,
) {
this.tool_result_cards.insert(tool_use_id, card);
}
}
}
} }
} }
} }

View file

@ -1037,12 +1037,12 @@ impl Thread {
log::info!("Running tool {}", tool_use.name); log::info!("Running tool {}", tool_use.name);
Some(cx.foreground_executor().spawn(async move { Some(cx.foreground_executor().spawn(async move {
let tool_result = tool_result.await.and_then(|output| { let tool_result = tool_result.await.and_then(|output| {
if let LanguageModelToolResultContent::Image(_) = &output.llm_output { if let LanguageModelToolResultContent::Image(_) = &output.llm_output
if !supports_images { && !supports_images
return Err(anyhow!( {
"Attempted to read an image, but this model doesn't support it.", return Err(anyhow!(
)); "Attempted to read an image, but this model doesn't support it.",
} ));
} }
Ok(output) Ok(output)
}); });

View file

@ -156,13 +156,13 @@ impl EditFileTool {
// It's also possible that the global config dir is configured to be inside the project, // It's also possible that the global config dir is configured to be inside the project,
// so check for that edge case too. // so check for that edge case too.
if let Ok(canonical_path) = std::fs::canonicalize(&input.path) { if let Ok(canonical_path) = std::fs::canonicalize(&input.path)
if canonical_path.starts_with(paths::config_dir()) { && canonical_path.starts_with(paths::config_dir())
return event_stream.authorize( {
format!("{} (global settings)", input.display_description), return event_stream.authorize(
cx, format!("{} (global settings)", input.display_description),
); cx,
} );
} }
// Check if path is inside the global config directory // Check if path is inside the global config directory

View file

@ -179,15 +179,14 @@ impl AgentTool for GrepTool {
// Check if this file should be excluded based on its worktree settings // Check if this file should be excluded based on its worktree settings
if let Ok(Some(project_path)) = project.read_with(cx, |project, cx| { if let Ok(Some(project_path)) = project.read_with(cx, |project, cx| {
project.find_project_path(&path, cx) project.find_project_path(&path, cx)
}) { })
if cx.update(|cx| { && cx.update(|cx| {
let worktree_settings = WorktreeSettings::get(Some((&project_path).into()), cx); let worktree_settings = WorktreeSettings::get(Some((&project_path).into()), cx);
worktree_settings.is_path_excluded(&project_path.path) worktree_settings.is_path_excluded(&project_path.path)
|| worktree_settings.is_path_private(&project_path.path) || worktree_settings.is_path_private(&project_path.path)
}).unwrap_or(false) { }).unwrap_or(false) {
continue; continue;
} }
}
while *parse_status.borrow() != ParseStatus::Idle { while *parse_status.borrow() != ParseStatus::Idle {
parse_status.changed().await?; parse_status.changed().await?;
@ -275,12 +274,11 @@ impl AgentTool for GrepTool {
output.extend(snapshot.text_for_range(range)); output.extend(snapshot.text_for_range(range));
output.push_str("\n```\n"); output.push_str("\n```\n");
if let Some(ancestor_range) = ancestor_range { if let Some(ancestor_range) = ancestor_range
if end_row < ancestor_range.end.row { && end_row < ancestor_range.end.row {
let remaining_lines = ancestor_range.end.row - end_row; let remaining_lines = ancestor_range.end.row - end_row;
writeln!(output, "\n{} lines remaining in ancestor node. Read the file to see all.", remaining_lines)?; writeln!(output, "\n{} lines remaining in ancestor node. Read the file to see all.", remaining_lines)?;
} }
}
matches_found += 1; matches_found += 1;
} }

View file

@ -203,14 +203,14 @@ impl AgentConnection for ClaudeAgentConnection {
.await .await
} }
if let Some(status) = child.status().await.log_err() { if let Some(status) = child.status().await.log_err()
if let Some(thread) = thread_rx.recv().await.ok() { && let Some(thread) = thread_rx.recv().await.ok()
thread {
.update(cx, |thread, cx| { thread
thread.emit_server_exited(status, cx); .update(cx, |thread, cx| {
}) thread.emit_server_exited(status, cx);
.ok(); })
} .ok();
} }
} }
}); });

View file

@ -116,15 +116,15 @@ pub struct LanguageModelParameters {
impl LanguageModelParameters { impl LanguageModelParameters {
pub fn matches(&self, model: &Arc<dyn LanguageModel>) -> bool { pub fn matches(&self, model: &Arc<dyn LanguageModel>) -> bool {
if let Some(provider) = &self.provider { if let Some(provider) = &self.provider
if provider.0 != model.provider_id().0 { && provider.0 != model.provider_id().0
return false; {
} return false;
} }
if let Some(setting_model) = &self.model { if let Some(setting_model) = &self.model
if *setting_model != model.id().0 { && *setting_model != model.id().0
return false; {
} return false;
} }
true true
} }

View file

@ -371,20 +371,20 @@ impl AcpThreadView {
let provider_id = provider_id.clone(); let provider_id = provider_id.clone();
let this = this.clone(); let this = this.clone();
move |_, ev, window, cx| { move |_, ev, window, cx| {
if let language_model::Event::ProviderStateChanged(updated_provider_id) = &ev { if let language_model::Event::ProviderStateChanged(updated_provider_id) = &ev
if &provider_id == updated_provider_id { && &provider_id == updated_provider_id
this.update(cx, |this, cx| { {
this.thread_state = Self::initial_state( this.update(cx, |this, cx| {
agent.clone(), this.thread_state = Self::initial_state(
this.workspace.clone(), agent.clone(),
this.project.clone(), this.workspace.clone(),
window, this.project.clone(),
cx, window,
); cx,
cx.notify(); );
}) cx.notify();
.ok(); })
} .ok();
} }
} }
}); });
@ -547,11 +547,11 @@ impl AcpThreadView {
} }
fn send(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn send(&mut self, window: &mut Window, cx: &mut Context<Self>) {
if let Some(thread) = self.thread() { if let Some(thread) = self.thread()
if thread.read(cx).status() != ThreadStatus::Idle { && thread.read(cx).status() != ThreadStatus::Idle
self.stop_current_and_send_new_message(window, cx); {
return; self.stop_current_and_send_new_message(window, cx);
} return;
} }
let contents = self let contents = self
@ -628,25 +628,24 @@ impl AcpThreadView {
return; return;
}; };
if let Some(index) = self.editing_message.take() { if let Some(index) = self.editing_message.take()
if let Some(editor) = self && let Some(editor) = self
.entry_view_state .entry_view_state
.read(cx) .read(cx)
.entry(index) .entry(index)
.and_then(|e| e.message_editor()) .and_then(|e| e.message_editor())
.cloned() .cloned()
{ {
editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| {
if let Some(user_message) = thread if let Some(user_message) = thread
.read(cx) .read(cx)
.entries() .entries()
.get(index) .get(index)
.and_then(|e| e.user_message()) .and_then(|e| e.user_message())
{ {
editor.set_message(user_message.chunks.clone(), window, cx); editor.set_message(user_message.chunks.clone(), window, cx);
} }
}) })
}
}; };
self.focus_handle(cx).focus(window); self.focus_handle(cx).focus(window);
cx.notify(); cx.notify();
@ -3265,62 +3264,61 @@ impl AcpThreadView {
}) })
}) })
.log_err() .log_err()
&& let Some(pop_up) = screen_window.entity(cx).log_err()
{ {
if let Some(pop_up) = screen_window.entity(cx).log_err() { self.notification_subscriptions
self.notification_subscriptions .entry(screen_window)
.entry(screen_window) .or_insert_with(Vec::new)
.or_insert_with(Vec::new) .push(cx.subscribe_in(&pop_up, window, {
.push(cx.subscribe_in(&pop_up, window, { |this, _, event, window, cx| match event {
|this, _, event, window, cx| match event { AgentNotificationEvent::Accepted => {
AgentNotificationEvent::Accepted => { let handle = window.window_handle();
let handle = window.window_handle(); cx.activate(true);
cx.activate(true);
let workspace_handle = this.workspace.clone(); let workspace_handle = this.workspace.clone();
// If there are multiple Zed windows, activate the correct one. // If there are multiple Zed windows, activate the correct one.
cx.defer(move |cx| { cx.defer(move |cx| {
handle handle
.update(cx, |_view, window, _cx| { .update(cx, |_view, window, _cx| {
window.activate_window(); window.activate_window();
if let Some(workspace) = workspace_handle.upgrade() { if let Some(workspace) = workspace_handle.upgrade() {
workspace.update(_cx, |workspace, cx| { workspace.update(_cx, |workspace, cx| {
workspace.focus_panel::<AgentPanel>(window, cx); workspace.focus_panel::<AgentPanel>(window, cx);
}); });
} }
}) })
.log_err(); .log_err();
}); });
this.dismiss_notifications(cx); this.dismiss_notifications(cx);
}
AgentNotificationEvent::Dismissed => {
this.dismiss_notifications(cx);
}
} }
})); AgentNotificationEvent::Dismissed => {
this.dismiss_notifications(cx);
}
}
}));
self.notifications.push(screen_window); self.notifications.push(screen_window);
// If the user manually refocuses the original window, dismiss the popup. // If the user manually refocuses the original window, dismiss the popup.
self.notification_subscriptions self.notification_subscriptions
.entry(screen_window) .entry(screen_window)
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push({ .push({
let pop_up_weak = pop_up.downgrade(); let pop_up_weak = pop_up.downgrade();
cx.observe_window_activation(window, move |_, window, cx| { cx.observe_window_activation(window, move |_, window, cx| {
if window.is_window_active() { if window.is_window_active()
if let Some(pop_up) = pop_up_weak.upgrade() { && let Some(pop_up) = pop_up_weak.upgrade()
pop_up.update(cx, |_, cx| { {
cx.emit(AgentNotificationEvent::Dismissed); pop_up.update(cx, |_, cx| {
}); cx.emit(AgentNotificationEvent::Dismissed);
} });
} }
}) })
}); });
}
} }
} }

View file

@ -1072,8 +1072,8 @@ impl ActiveThread {
} }
ThreadEvent::MessageEdited(message_id) => { ThreadEvent::MessageEdited(message_id) => {
self.clear_last_error(); self.clear_last_error();
if let Some(index) = self.messages.iter().position(|id| id == message_id) { if let Some(index) = self.messages.iter().position(|id| id == message_id)
if let Some(rendered_message) = self.thread.update(cx, |thread, cx| { && let Some(rendered_message) = self.thread.update(cx, |thread, cx| {
thread.message(*message_id).map(|message| { thread.message(*message_id).map(|message| {
let mut rendered_message = RenderedMessage { let mut rendered_message = RenderedMessage {
language_registry: self.language_registry.clone(), language_registry: self.language_registry.clone(),
@ -1084,14 +1084,14 @@ impl ActiveThread {
} }
rendered_message rendered_message
}) })
}) { })
self.list_state.splice(index..index + 1, 1); {
self.rendered_messages_by_id self.list_state.splice(index..index + 1, 1);
.insert(*message_id, rendered_message); self.rendered_messages_by_id
self.scroll_to_bottom(cx); .insert(*message_id, rendered_message);
self.save_thread(cx); self.scroll_to_bottom(cx);
cx.notify(); self.save_thread(cx);
} cx.notify();
} }
} }
ThreadEvent::MessageDeleted(message_id) => { ThreadEvent::MessageDeleted(message_id) => {
@ -1272,62 +1272,61 @@ impl ActiveThread {
}) })
}) })
.log_err() .log_err()
&& let Some(pop_up) = screen_window.entity(cx).log_err()
{ {
if let Some(pop_up) = screen_window.entity(cx).log_err() { self.notification_subscriptions
self.notification_subscriptions .entry(screen_window)
.entry(screen_window) .or_insert_with(Vec::new)
.or_insert_with(Vec::new) .push(cx.subscribe_in(&pop_up, window, {
.push(cx.subscribe_in(&pop_up, window, { |this, _, event, window, cx| match event {
|this, _, event, window, cx| match event { AgentNotificationEvent::Accepted => {
AgentNotificationEvent::Accepted => { let handle = window.window_handle();
let handle = window.window_handle(); cx.activate(true);
cx.activate(true);
let workspace_handle = this.workspace.clone(); let workspace_handle = this.workspace.clone();
// If there are multiple Zed windows, activate the correct one. // If there are multiple Zed windows, activate the correct one.
cx.defer(move |cx| { cx.defer(move |cx| {
handle handle
.update(cx, |_view, window, _cx| { .update(cx, |_view, window, _cx| {
window.activate_window(); window.activate_window();
if let Some(workspace) = workspace_handle.upgrade() { if let Some(workspace) = workspace_handle.upgrade() {
workspace.update(_cx, |workspace, cx| { workspace.update(_cx, |workspace, cx| {
workspace.focus_panel::<AgentPanel>(window, cx); workspace.focus_panel::<AgentPanel>(window, cx);
}); });
} }
}) })
.log_err(); .log_err();
}); });
this.dismiss_notifications(cx); this.dismiss_notifications(cx);
}
AgentNotificationEvent::Dismissed => {
this.dismiss_notifications(cx);
}
} }
})); AgentNotificationEvent::Dismissed => {
this.dismiss_notifications(cx);
}
}
}));
self.notifications.push(screen_window); self.notifications.push(screen_window);
// If the user manually refocuses the original window, dismiss the popup. // If the user manually refocuses the original window, dismiss the popup.
self.notification_subscriptions self.notification_subscriptions
.entry(screen_window) .entry(screen_window)
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push({ .push({
let pop_up_weak = pop_up.downgrade(); let pop_up_weak = pop_up.downgrade();
cx.observe_window_activation(window, move |_, window, cx| { cx.observe_window_activation(window, move |_, window, cx| {
if window.is_window_active() { if window.is_window_active()
if let Some(pop_up) = pop_up_weak.upgrade() { && let Some(pop_up) = pop_up_weak.upgrade()
pop_up.update(cx, |_, cx| { {
cx.emit(AgentNotificationEvent::Dismissed); pop_up.update(cx, |_, cx| {
}); cx.emit(AgentNotificationEvent::Dismissed);
} });
} }
}) })
}); });
}
} }
} }
@ -2269,13 +2268,12 @@ impl ActiveThread {
let mut error = None; let mut error = None;
if let Some(last_restore_checkpoint) = if let Some(last_restore_checkpoint) =
self.thread.read(cx).last_restore_checkpoint() self.thread.read(cx).last_restore_checkpoint()
&& last_restore_checkpoint.message_id() == message_id
{ {
if last_restore_checkpoint.message_id() == message_id { match last_restore_checkpoint {
match last_restore_checkpoint { LastRestoreCheckpoint::Pending { .. } => is_pending = true,
LastRestoreCheckpoint::Pending { .. } => is_pending = true, LastRestoreCheckpoint::Error { error: err, .. } => {
LastRestoreCheckpoint::Error { error: err, .. } => { error = Some(err.clone());
error = Some(err.clone());
}
} }
} }
} }

View file

@ -163,10 +163,10 @@ impl ConfigurationSource {
.read(cx) .read(cx)
.text(cx); .text(cx);
let settings = serde_json_lenient::from_str::<serde_json::Value>(&text)?; let settings = serde_json_lenient::from_str::<serde_json::Value>(&text)?;
if let Some(settings_validator) = settings_validator { if let Some(settings_validator) = settings_validator
if let Err(error) = settings_validator.validate(&settings) { && let Err(error) = settings_validator.validate(&settings)
return Err(anyhow::anyhow!(error.to_string())); {
} return Err(anyhow::anyhow!(error.to_string()));
} }
Ok(( Ok((
id.clone(), id.clone(),
@ -716,24 +716,24 @@ fn wait_for_context_server(
project::context_server_store::Event::ServerStatusChanged { server_id, status } => { project::context_server_store::Event::ServerStatusChanged { server_id, status } => {
match status { match status {
ContextServerStatus::Running => { ContextServerStatus::Running => {
if server_id == &context_server_id { if server_id == &context_server_id
if let Some(tx) = tx.lock().unwrap().take() { && let Some(tx) = tx.lock().unwrap().take()
let _ = tx.send(Ok(())); {
} let _ = tx.send(Ok(()));
} }
} }
ContextServerStatus::Stopped => { ContextServerStatus::Stopped => {
if server_id == &context_server_id { if server_id == &context_server_id
if let Some(tx) = tx.lock().unwrap().take() { && let Some(tx) = tx.lock().unwrap().take()
let _ = tx.send(Err("Context server stopped running".into())); {
} let _ = tx.send(Err("Context server stopped running".into()));
} }
} }
ContextServerStatus::Error(error) => { ContextServerStatus::Error(error) => {
if server_id == &context_server_id { if server_id == &context_server_id
if let Some(tx) = tx.lock().unwrap().take() { && let Some(tx) = tx.lock().unwrap().take()
let _ = tx.send(Err(error.clone())); {
} let _ = tx.send(Err(error.clone()));
} }
} }
_ => {} _ => {}

View file

@ -191,10 +191,10 @@ impl PickerDelegate for ToolPickerDelegate {
BTreeMap::default(); BTreeMap::default();
for item in all_items.iter() { for item in all_items.iter() {
if let PickerItem::Tool { server_id, name } = item.clone() { if let PickerItem::Tool { server_id, name } = item.clone()
if name.contains(&query) { && name.contains(&query)
tools_by_provider.entry(server_id).or_default().push(name); {
} tools_by_provider.entry(server_id).or_default().push(name);
} }
} }

View file

@ -1043,18 +1043,18 @@ impl ToolbarItemView for AgentDiffToolbar {
return self.location(cx); return self.location(cx);
} }
if let Some(editor) = item.act_as::<Editor>(cx) { if let Some(editor) = item.act_as::<Editor>(cx)
if editor.read(cx).mode().is_full() { && editor.read(cx).mode().is_full()
let agent_diff = AgentDiff::global(cx); {
let agent_diff = AgentDiff::global(cx);
self.active_item = Some(AgentDiffToolbarItem::Editor { self.active_item = Some(AgentDiffToolbarItem::Editor {
editor: editor.downgrade(), editor: editor.downgrade(),
state: agent_diff.read(cx).editor_state(&editor.downgrade()), state: agent_diff.read(cx).editor_state(&editor.downgrade()),
_diff_subscription: cx.observe(&agent_diff, Self::handle_diff_notify), _diff_subscription: cx.observe(&agent_diff, Self::handle_diff_notify),
}); });
return self.location(cx); return self.location(cx);
}
} }
} }
@ -1538,16 +1538,10 @@ impl AgentDiff {
) { ) {
match event { match event {
workspace::Event::ItemAdded { item } => { workspace::Event::ItemAdded { item } => {
if let Some(editor) = item.downcast::<Editor>() { if let Some(editor) = item.downcast::<Editor>()
if let Some(buffer) = Self::full_editor_buffer(editor.read(cx), cx) { && let Some(buffer) = Self::full_editor_buffer(editor.read(cx), cx)
self.register_editor( {
workspace.downgrade(), self.register_editor(workspace.downgrade(), buffer.clone(), editor, window, cx);
buffer.clone(),
editor,
window,
cx,
);
}
} }
} }
_ => {} _ => {}
@ -1850,22 +1844,22 @@ impl AgentDiff {
let thread = thread.upgrade()?; let thread = thread.upgrade()?;
if let PostReviewState::AllReviewed = review(&editor, &thread, window, cx) { if let PostReviewState::AllReviewed = review(&editor, &thread, window, cx)
if let Some(curr_buffer) = editor.read(cx).buffer().read(cx).as_singleton() { && let Some(curr_buffer) = editor.read(cx).buffer().read(cx).as_singleton()
let changed_buffers = thread.action_log(cx).read(cx).changed_buffers(cx); {
let changed_buffers = thread.action_log(cx).read(cx).changed_buffers(cx);
let mut keys = changed_buffers.keys().cycle(); let mut keys = changed_buffers.keys().cycle();
keys.find(|k| *k == &curr_buffer); keys.find(|k| *k == &curr_buffer);
let next_project_path = keys let next_project_path = keys
.next() .next()
.filter(|k| *k != &curr_buffer) .filter(|k| *k != &curr_buffer)
.and_then(|after| after.read(cx).project_path(cx)); .and_then(|after| after.read(cx).project_path(cx));
if let Some(path) = next_project_path { if let Some(path) = next_project_path {
let task = workspace.open_path(path, None, true, window, cx); let task = workspace.open_path(path, None, true, window, cx);
let task = cx.spawn(async move |_, _cx| task.await.map(|_| ())); let task = cx.spawn(async move |_, _cx| task.await.map(|_| ()));
return Some(task); return Some(task);
}
} }
} }

View file

@ -1398,14 +1398,13 @@ impl AgentPanel {
if LanguageModelRegistry::read_global(cx) if LanguageModelRegistry::read_global(cx)
.default_model() .default_model()
.map_or(true, |model| model.provider.id() != provider.id()) .map_or(true, |model| model.provider.id() != provider.id())
&& let Some(model) = provider.default_model(cx)
{ {
if let Some(model) = provider.default_model(cx) { update_settings_file::<AgentSettings>(
update_settings_file::<AgentSettings>( self.fs.clone(),
self.fs.clone(), cx,
cx, move |settings, _| settings.set_model(model),
move |settings, _| settings.set_model(model), );
);
}
} }
self.new_thread(&NewThread::default(), window, cx); self.new_thread(&NewThread::default(), window, cx);

View file

@ -352,12 +352,12 @@ impl CodegenAlternative {
event: &multi_buffer::Event, event: &multi_buffer::Event,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if let multi_buffer::Event::TransactionUndone { transaction_id } = event { if let multi_buffer::Event::TransactionUndone { transaction_id } = event
if self.transformation_transaction_id == Some(*transaction_id) { && self.transformation_transaction_id == Some(*transaction_id)
self.transformation_transaction_id = None; {
self.generation = Task::ready(()); self.transformation_transaction_id = None;
cx.emit(CodegenEvent::Undone); self.generation = Task::ready(());
} cx.emit(CodegenEvent::Undone);
} }
} }
@ -576,38 +576,34 @@ impl CodegenAlternative {
let mut lines = chunk.split('\n').peekable(); let mut lines = chunk.split('\n').peekable();
while let Some(line) = lines.next() { while let Some(line) = lines.next() {
new_text.push_str(line); new_text.push_str(line);
if line_indent.is_none() { if line_indent.is_none()
if let Some(non_whitespace_ch_ix) = && let Some(non_whitespace_ch_ix) =
new_text.find(|ch: char| !ch.is_whitespace()) new_text.find(|ch: char| !ch.is_whitespace())
{ {
line_indent = Some(non_whitespace_ch_ix); line_indent = Some(non_whitespace_ch_ix);
base_indent = base_indent.or(line_indent); base_indent = base_indent.or(line_indent);
let line_indent = line_indent.unwrap(); let line_indent = line_indent.unwrap();
let base_indent = base_indent.unwrap(); let base_indent = base_indent.unwrap();
let indent_delta = let indent_delta = line_indent as i32 - base_indent as i32;
line_indent as i32 - base_indent as i32; let mut corrected_indent_len = cmp::max(
let mut corrected_indent_len = cmp::max( 0,
0, suggested_line_indent.len as i32 + indent_delta,
suggested_line_indent.len as i32 + indent_delta, )
) as usize;
as usize; if first_line {
if first_line { corrected_indent_len = corrected_indent_len
corrected_indent_len = corrected_indent_len .saturating_sub(selection_start.column as usize);
.saturating_sub(
selection_start.column as usize,
);
}
let indent_char = suggested_line_indent.char();
let mut indent_buffer = [0; 4];
let indent_str =
indent_char.encode_utf8(&mut indent_buffer);
new_text.replace_range(
..line_indent,
&indent_str.repeat(corrected_indent_len),
);
} }
let indent_char = suggested_line_indent.char();
let mut indent_buffer = [0; 4];
let indent_str =
indent_char.encode_utf8(&mut indent_buffer);
new_text.replace_range(
..line_indent,
&indent_str.repeat(corrected_indent_len),
);
} }
if line_indent.is_some() { if line_indent.is_some() {

View file

@ -368,10 +368,10 @@ impl ContextStrip {
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if let Some(suggested) = self.suggested_context(cx) { if let Some(suggested) = self.suggested_context(cx)
if self.is_suggested_focused(&self.added_contexts(cx)) { && self.is_suggested_focused(&self.added_contexts(cx))
self.add_suggested_context(&suggested, cx); {
} self.add_suggested_context(&suggested, cx);
} }
} }

View file

@ -182,13 +182,13 @@ impl InlineAssistant {
match event { match event {
workspace::Event::UserSavedItem { item, .. } => { workspace::Event::UserSavedItem { item, .. } => {
// When the user manually saves an editor, automatically accepts all finished transformations. // When the user manually saves an editor, automatically accepts all finished transformations.
if let Some(editor) = item.upgrade().and_then(|item| item.act_as::<Editor>(cx)) { if let Some(editor) = item.upgrade().and_then(|item| item.act_as::<Editor>(cx))
if let Some(editor_assists) = self.assists_by_editor.get(&editor.downgrade()) { && let Some(editor_assists) = self.assists_by_editor.get(&editor.downgrade())
for assist_id in editor_assists.assist_ids.clone() { {
let assist = &self.assists[&assist_id]; for assist_id in editor_assists.assist_ids.clone() {
if let CodegenStatus::Done = assist.codegen.read(cx).status(cx) { let assist = &self.assists[&assist_id];
self.finish_assist(assist_id, false, window, cx) if let CodegenStatus::Done = assist.codegen.read(cx).status(cx) {
} self.finish_assist(assist_id, false, window, cx)
} }
} }
} }
@ -342,13 +342,11 @@ impl InlineAssistant {
) )
.await .await
.ok(); .ok();
if let Some(answer) = answer { if let Some(answer) = answer
if answer == 0 { && answer == 0
cx.update(|window, cx| { {
window.dispatch_action(Box::new(OpenSettings), cx) cx.update(|window, cx| window.dispatch_action(Box::new(OpenSettings), cx))
})
.ok(); .ok();
}
} }
anyhow::Ok(()) anyhow::Ok(())
}) })
@ -435,11 +433,11 @@ impl InlineAssistant {
} }
} }
if let Some(prev_selection) = selections.last_mut() { if let Some(prev_selection) = selections.last_mut()
if selection.start <= prev_selection.end { && selection.start <= prev_selection.end
prev_selection.end = selection.end; {
continue; prev_selection.end = selection.end;
} continue;
} }
let latest_selection = newest_selection.get_or_insert_with(|| selection.clone()); let latest_selection = newest_selection.get_or_insert_with(|| selection.clone());
@ -985,14 +983,13 @@ impl InlineAssistant {
EditorEvent::SelectionsChanged { .. } => { EditorEvent::SelectionsChanged { .. } => {
for assist_id in editor_assists.assist_ids.clone() { for assist_id in editor_assists.assist_ids.clone() {
let assist = &self.assists[&assist_id]; let assist = &self.assists[&assist_id];
if let Some(decorations) = assist.decorations.as_ref() { if let Some(decorations) = assist.decorations.as_ref()
if decorations && decorations
.prompt_editor .prompt_editor
.focus_handle(cx) .focus_handle(cx)
.is_focused(window) .is_focused(window)
{ {
return; return;
}
} }
} }
@ -1503,20 +1500,18 @@ impl InlineAssistant {
window: &mut Window, window: &mut Window,
cx: &mut App, cx: &mut App,
) -> Option<InlineAssistTarget> { ) -> Option<InlineAssistTarget> {
if let Some(terminal_panel) = workspace.panel::<TerminalPanel>(cx) { if let Some(terminal_panel) = workspace.panel::<TerminalPanel>(cx)
if terminal_panel && terminal_panel
.read(cx) .read(cx)
.focus_handle(cx) .focus_handle(cx)
.contains_focused(window, cx) .contains_focused(window, cx)
{ && let Some(terminal_view) = terminal_panel.read(cx).pane().and_then(|pane| {
if let Some(terminal_view) = terminal_panel.read(cx).pane().and_then(|pane| { pane.read(cx)
pane.read(cx) .active_item()
.active_item() .and_then(|t| t.downcast::<TerminalView>())
.and_then(|t| t.downcast::<TerminalView>()) })
}) { {
return Some(InlineAssistTarget::Terminal(terminal_view)); return Some(InlineAssistTarget::Terminal(terminal_view));
}
}
} }
let context_editor = agent_panel let context_editor = agent_panel
@ -1741,22 +1736,20 @@ impl InlineAssist {
return; return;
}; };
if let CodegenStatus::Error(error) = codegen.read(cx).status(cx) { if let CodegenStatus::Error(error) = codegen.read(cx).status(cx)
if assist.decorations.is_none() { && assist.decorations.is_none()
if let Some(workspace) = assist.workspace.upgrade() { && let Some(workspace) = assist.workspace.upgrade()
let error = format!("Inline assistant error: {}", error); {
workspace.update(cx, |workspace, cx| { let error = format!("Inline assistant error: {}", error);
struct InlineAssistantError; workspace.update(cx, |workspace, cx| {
struct InlineAssistantError;
let id = let id = NotificationId::composite::<InlineAssistantError>(
NotificationId::composite::<InlineAssistantError>( assist_id.0,
assist_id.0, );
);
workspace.show_toast(Toast::new(id, error), cx); workspace.show_toast(Toast::new(id, error), cx);
}) })
}
}
} }
if assist.decorations.is_none() { if assist.decorations.is_none() {
@ -1821,18 +1814,18 @@ impl CodeActionProvider for AssistantCodeActionProvider {
has_diagnostics = true; has_diagnostics = true;
} }
if has_diagnostics { if has_diagnostics {
if let Some(symbols_containing_start) = snapshot.symbols_containing(range.start, None) { if let Some(symbols_containing_start) = snapshot.symbols_containing(range.start, None)
if let Some(symbol) = symbols_containing_start.last() { && let Some(symbol) = symbols_containing_start.last()
range.start = cmp::min(range.start, symbol.range.start.to_point(&snapshot)); {
range.end = cmp::max(range.end, symbol.range.end.to_point(&snapshot)); range.start = cmp::min(range.start, symbol.range.start.to_point(&snapshot));
} range.end = cmp::max(range.end, symbol.range.end.to_point(&snapshot));
} }
if let Some(symbols_containing_end) = snapshot.symbols_containing(range.end, None) { if let Some(symbols_containing_end) = snapshot.symbols_containing(range.end, None)
if let Some(symbol) = symbols_containing_end.last() { && let Some(symbol) = symbols_containing_end.last()
range.start = cmp::min(range.start, symbol.range.start.to_point(&snapshot)); {
range.end = cmp::max(range.end, symbol.range.end.to_point(&snapshot)); range.start = cmp::min(range.start, symbol.range.start.to_point(&snapshot));
} range.end = cmp::max(range.end, symbol.range.end.to_point(&snapshot));
} }
Task::ready(Ok(vec![CodeAction { Task::ready(Ok(vec![CodeAction {

View file

@ -388,20 +388,20 @@ impl TerminalInlineAssistant {
window: &mut Window, window: &mut Window,
cx: &mut App, cx: &mut App,
) { ) {
if let Some(assist) = self.assists.get_mut(&assist_id) { if let Some(assist) = self.assists.get_mut(&assist_id)
if let Some(prompt_editor) = assist.prompt_editor.as_ref().cloned() { && let Some(prompt_editor) = assist.prompt_editor.as_ref().cloned()
assist {
.terminal assist
.update(cx, |terminal, cx| { .terminal
terminal.clear_block_below_cursor(cx); .update(cx, |terminal, cx| {
let block = terminal_view::BlockProperties { terminal.clear_block_below_cursor(cx);
height, let block = terminal_view::BlockProperties {
render: Box::new(move |_| prompt_editor.clone().into_any_element()), height,
}; render: Box::new(move |_| prompt_editor.clone().into_any_element()),
terminal.set_block_below_cursor(block, window, cx); };
}) terminal.set_block_below_cursor(block, window, cx);
.log_err(); })
} .log_err();
} }
} }
} }
@ -450,23 +450,20 @@ impl TerminalInlineAssist {
return; return;
}; };
if let CodegenStatus::Error(error) = &codegen.read(cx).status { if let CodegenStatus::Error(error) = &codegen.read(cx).status
if assist.prompt_editor.is_none() { && assist.prompt_editor.is_none()
if let Some(workspace) = assist.workspace.upgrade() { && let Some(workspace) = assist.workspace.upgrade()
let error = {
format!("Terminal inline assistant error: {}", error); let error = format!("Terminal inline assistant error: {}", error);
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
struct InlineAssistantError; struct InlineAssistantError;
let id = let id = NotificationId::composite::<InlineAssistantError>(
NotificationId::composite::<InlineAssistantError>( assist_id.0,
assist_id.0, );
);
workspace.show_toast(Toast::new(id, error), cx); workspace.show_toast(Toast::new(id, error), cx);
}) })
}
}
} }
if assist.prompt_editor.is_none() { if assist.prompt_editor.is_none() {

View file

@ -745,28 +745,27 @@ impl TextThreadEditor {
) { ) {
if let Some(invoked_slash_command) = if let Some(invoked_slash_command) =
self.context.read(cx).invoked_slash_command(&command_id) self.context.read(cx).invoked_slash_command(&command_id)
&& let InvokedSlashCommandStatus::Finished = invoked_slash_command.status
{ {
if let InvokedSlashCommandStatus::Finished = invoked_slash_command.status { let run_commands_in_ranges = invoked_slash_command.run_commands_in_ranges.clone();
let run_commands_in_ranges = invoked_slash_command.run_commands_in_ranges.clone(); for range in run_commands_in_ranges {
for range in run_commands_in_ranges { let commands = self.context.update(cx, |context, cx| {
let commands = self.context.update(cx, |context, cx| { context.reparse(cx);
context.reparse(cx); context
context .pending_commands_for_range(range.clone(), cx)
.pending_commands_for_range(range.clone(), cx) .to_vec()
.to_vec() });
});
for command in commands { for command in commands {
self.run_command( self.run_command(
command.source_range, command.source_range,
&command.name, &command.name,
&command.arguments, &command.arguments,
false, false,
self.workspace.clone(), self.workspace.clone(),
window, window,
cx, cx,
); );
}
} }
} }
} }

View file

@ -166,14 +166,13 @@ impl ThreadHistory {
this.all_entries.len().saturating_sub(1), this.all_entries.len().saturating_sub(1),
cx, cx,
); );
} else if let Some(prev_id) = previously_selected_entry { } else if let Some(prev_id) = previously_selected_entry
if let Some(new_ix) = this && let Some(new_ix) = this
.all_entries .all_entries
.iter() .iter()
.position(|probe| probe.id() == prev_id) .position(|probe| probe.id() == prev_id)
{ {
this.set_selected_entry_index(new_ix, cx); this.set_selected_entry_index(new_ix, cx);
}
} }
} }
SearchState::Searching { query, .. } | SearchState::Searched { query, .. } => { SearchState::Searching { query, .. } | SearchState::Searched { query, .. } => {

View file

@ -1076,20 +1076,20 @@ impl AssistantContext {
timestamp, timestamp,
.. ..
} => { } => {
if let Some(slash_command) = self.invoked_slash_commands.get_mut(&id) { if let Some(slash_command) = self.invoked_slash_commands.get_mut(&id)
if timestamp > slash_command.timestamp { && timestamp > slash_command.timestamp
slash_command.timestamp = timestamp; {
match error_message { slash_command.timestamp = timestamp;
Some(message) => { match error_message {
slash_command.status = Some(message) => {
InvokedSlashCommandStatus::Error(message.into()); slash_command.status =
} InvokedSlashCommandStatus::Error(message.into());
None => { }
slash_command.status = InvokedSlashCommandStatus::Finished; None => {
} slash_command.status = InvokedSlashCommandStatus::Finished;
} }
cx.emit(ContextEvent::InvokedSlashCommandChanged { command_id: id });
} }
cx.emit(ContextEvent::InvokedSlashCommandChanged { command_id: id });
} }
} }
ContextOperation::BufferOperation(_) => unreachable!(), ContextOperation::BufferOperation(_) => unreachable!(),
@ -1368,10 +1368,10 @@ impl AssistantContext {
continue; continue;
} }
if let Some(last_anchor) = last_anchor { if let Some(last_anchor) = last_anchor
if message.id == last_anchor { && message.id == last_anchor
hit_last_anchor = true; {
} hit_last_anchor = true;
} }
new_anchor_needs_caching = new_anchor_needs_caching new_anchor_needs_caching = new_anchor_needs_caching
@ -1406,10 +1406,10 @@ impl AssistantContext {
if !self.pending_completions.is_empty() { if !self.pending_completions.is_empty() {
return; return;
} }
if let Some(cache_configuration) = cache_configuration { if let Some(cache_configuration) = cache_configuration
if !cache_configuration.should_speculate { && !cache_configuration.should_speculate
return; {
} return;
} }
let request = { let request = {
@ -1552,25 +1552,24 @@ impl AssistantContext {
}) })
.map(ToOwned::to_owned) .map(ToOwned::to_owned)
.collect::<SmallVec<_>>(); .collect::<SmallVec<_>>();
if let Some(command) = self.slash_commands.command(name, cx) { if let Some(command) = self.slash_commands.command(name, cx)
if !command.requires_argument() || !arguments.is_empty() { && (!command.requires_argument() || !arguments.is_empty())
let start_ix = offset + command_line.name.start - 1; {
let end_ix = offset let start_ix = offset + command_line.name.start - 1;
+ command_line let end_ix = offset
.arguments + command_line
.last() .arguments
.map_or(command_line.name.end, |argument| argument.end); .last()
let source_range = .map_or(command_line.name.end, |argument| argument.end);
buffer.anchor_after(start_ix)..buffer.anchor_after(end_ix); let source_range = buffer.anchor_after(start_ix)..buffer.anchor_after(end_ix);
let pending_command = ParsedSlashCommand { let pending_command = ParsedSlashCommand {
name: name.to_string(), name: name.to_string(),
arguments, arguments,
source_range, source_range,
status: PendingSlashCommandStatus::Idle, status: PendingSlashCommandStatus::Idle,
}; };
updated.push(pending_command.clone()); updated.push(pending_command.clone());
new_commands.push(pending_command); new_commands.push(pending_command);
}
} }
} }
@ -1799,14 +1798,13 @@ impl AssistantContext {
}); });
let end = this.buffer.read(cx).anchor_before(insert_position); let end = this.buffer.read(cx).anchor_before(insert_position);
if run_commands_in_text { if run_commands_in_text
if let Some(invoked_slash_command) = && let Some(invoked_slash_command) =
this.invoked_slash_commands.get_mut(&command_id) this.invoked_slash_commands.get_mut(&command_id)
{ {
invoked_slash_command invoked_slash_command
.run_commands_in_ranges .run_commands_in_ranges
.push(start..end); .push(start..end);
}
} }
} }
SlashCommandEvent::EndSection => { SlashCommandEvent::EndSection => {
@ -2741,10 +2739,10 @@ impl AssistantContext {
} }
this.read_with(cx, |this, _cx| { this.read_with(cx, |this, _cx| {
if let Some(summary) = this.summary.content() { if let Some(summary) = this.summary.content()
if summary.text.is_empty() { && summary.text.is_empty()
bail!("Model generated an empty summary"); {
} bail!("Model generated an empty summary");
} }
Ok(()) Ok(())
})??; })??;
@ -2924,18 +2922,18 @@ impl AssistantContext {
fs.create_dir(contexts_dir().as_ref()).await?; fs.create_dir(contexts_dir().as_ref()).await?;
// rename before write ensures that only one file exists // rename before write ensures that only one file exists
if let Some(old_path) = old_path.as_ref() { if let Some(old_path) = old_path.as_ref()
if new_path.as_path() != old_path.as_ref() { && new_path.as_path() != old_path.as_ref()
fs.rename( {
old_path, fs.rename(
&new_path, old_path,
RenameOptions { &new_path,
overwrite: true, RenameOptions {
ignore_if_exists: true, overwrite: true,
}, ignore_if_exists: true,
) },
.await?; )
} .await?;
} }
// update path before write in case it fails // update path before write in case it fails

View file

@ -894,34 +894,33 @@ impl ContextStore {
return; return;
}; };
if protocol.capable(context_server::protocol::ServerCapability::Prompts) { if protocol.capable(context_server::protocol::ServerCapability::Prompts)
if let Some(response) = protocol && let Some(response) = protocol
.request::<context_server::types::requests::PromptsList>(()) .request::<context_server::types::requests::PromptsList>(())
.await .await
.log_err() .log_err()
{ {
let slash_command_ids = response let slash_command_ids = response
.prompts .prompts
.into_iter() .into_iter()
.filter(assistant_slash_commands::acceptable_prompt) .filter(assistant_slash_commands::acceptable_prompt)
.map(|prompt| { .map(|prompt| {
log::info!("registering context server command: {:?}", prompt.name); log::info!("registering context server command: {:?}", prompt.name);
slash_command_working_set.insert(Arc::new( slash_command_working_set.insert(Arc::new(
assistant_slash_commands::ContextServerSlashCommand::new( assistant_slash_commands::ContextServerSlashCommand::new(
context_server_store.clone(), context_server_store.clone(),
server.id(), server.id(),
prompt, prompt,
), ),
)) ))
})
.collect::<Vec<_>>();
this.update(cx, |this, _cx| {
this.context_server_slash_command_ids
.insert(server_id.clone(), slash_command_ids);
}) })
.log_err(); .collect::<Vec<_>>();
}
this.update(cx, |this, _cx| {
this.context_server_slash_command_ids
.insert(server_id.clone(), slash_command_ids);
})
.log_err();
} }
}) })
.detach(); .detach();

View file

@ -39,10 +39,10 @@ impl SlashCommand for ContextServerSlashCommand {
fn label(&self, cx: &App) -> language::CodeLabel { fn label(&self, cx: &App) -> language::CodeLabel {
let mut parts = vec![self.prompt.name.as_str()]; let mut parts = vec![self.prompt.name.as_str()];
if let Some(args) = &self.prompt.arguments { if let Some(args) = &self.prompt.arguments
if let Some(arg) = args.first() { && let Some(arg) = args.first()
parts.push(arg.name.as_str()); {
} parts.push(arg.name.as_str());
} }
create_label_for_command(parts[0], &parts[1..], cx) create_label_for_command(parts[0], &parts[1..], cx)
} }

View file

@ -66,23 +66,22 @@ impl SlashCommand for DeltaSlashCommand {
.metadata .metadata
.as_ref() .as_ref()
.and_then(|value| serde_json::from_value::<FileCommandMetadata>(value.clone()).ok()) .and_then(|value| serde_json::from_value::<FileCommandMetadata>(value.clone()).ok())
&& paths.insert(metadata.path.clone())
{ {
if paths.insert(metadata.path.clone()) { file_command_old_outputs.push(
file_command_old_outputs.push( context_buffer
context_buffer .as_rope()
.as_rope() .slice(section.range.to_offset(&context_buffer)),
.slice(section.range.to_offset(&context_buffer)), );
); file_command_new_outputs.push(Arc::new(FileSlashCommand).run(
file_command_new_outputs.push(Arc::new(FileSlashCommand).run( std::slice::from_ref(&metadata.path),
std::slice::from_ref(&metadata.path), context_slash_command_output_sections,
context_slash_command_output_sections, context_buffer.clone(),
context_buffer.clone(), workspace.clone(),
workspace.clone(), delegate.clone(),
delegate.clone(), window,
window, cx,
cx, ));
));
}
} }
} }
@ -95,25 +94,25 @@ impl SlashCommand for DeltaSlashCommand {
.into_iter() .into_iter()
.zip(file_command_new_outputs) .zip(file_command_new_outputs)
{ {
if let Ok(new_output) = new_output { if let Ok(new_output) = new_output
if let Ok(new_output) = SlashCommandOutput::from_event_stream(new_output).await && let Ok(new_output) = SlashCommandOutput::from_event_stream(new_output).await
{ && let Some(file_command_range) = new_output.sections.first()
if let Some(file_command_range) = new_output.sections.first() { {
let new_text = &new_output.text[file_command_range.range.clone()]; let new_text = &new_output.text[file_command_range.range.clone()];
if old_text.chars().ne(new_text.chars()) { if old_text.chars().ne(new_text.chars()) {
changes_detected = true; changes_detected = true;
output.sections.extend(new_output.sections.into_iter().map( output
|section| SlashCommandOutputSection { .sections
range: output.text.len() + section.range.start .extend(new_output.sections.into_iter().map(|section| {
..output.text.len() + section.range.end, SlashCommandOutputSection {
icon: section.icon, range: output.text.len() + section.range.start
label: section.label, ..output.text.len() + section.range.end,
metadata: section.metadata, icon: section.icon,
}, label: section.label,
)); metadata: section.metadata,
output.text.push_str(&new_output.text); }
} }));
} output.text.push_str(&new_output.text);
} }
} }
} }

View file

@ -280,10 +280,10 @@ fn collect_diagnostics(
let mut project_summary = DiagnosticSummary::default(); let mut project_summary = DiagnosticSummary::default();
for (project_path, path, summary) in diagnostic_summaries { for (project_path, path, summary) in diagnostic_summaries {
if let Some(path_matcher) = &options.path_matcher { if let Some(path_matcher) = &options.path_matcher
if !path_matcher.is_match(&path) { && !path_matcher.is_match(&path)
continue; {
} continue;
} }
project_summary.error_count += summary.error_count; project_summary.error_count += summary.error_count;

View file

@ -195,16 +195,14 @@ fn tab_items_for_queries(
} }
for editor in workspace.items_of_type::<Editor>(cx) { for editor in workspace.items_of_type::<Editor>(cx) {
if let Some(buffer) = editor.read(cx).buffer().read(cx).as_singleton() { if let Some(buffer) = editor.read(cx).buffer().read(cx).as_singleton()
if let Some(timestamp) = && let Some(timestamp) =
timestamps_by_entity_id.get(&editor.entity_id()) timestamps_by_entity_id.get(&editor.entity_id())
{ && visited_buffers.insert(buffer.read(cx).remote_id())
if visited_buffers.insert(buffer.read(cx).remote_id()) { {
let snapshot = buffer.read(cx).snapshot(); let snapshot = buffer.read(cx).snapshot();
let full_path = snapshot.resolve_file_path(cx, true); let full_path = snapshot.resolve_file_path(cx, true);
open_buffers.push((full_path, snapshot, *timestamp)); open_buffers.push((full_path, snapshot, *timestamp));
}
}
} }
} }

View file

@ -24,16 +24,16 @@ pub fn adapt_schema_to_format(
fn preprocess_json_schema(json: &mut Value) -> Result<()> { fn preprocess_json_schema(json: &mut Value) -> Result<()> {
// `additionalProperties` defaults to `false` unless explicitly specified. // `additionalProperties` defaults to `false` unless explicitly specified.
// This prevents models from hallucinating tool parameters. // This prevents models from hallucinating tool parameters.
if let Value::Object(obj) = json { if let Value::Object(obj) = json
if matches!(obj.get("type"), Some(Value::String(s)) if s == "object") { && matches!(obj.get("type"), Some(Value::String(s)) if s == "object")
if !obj.contains_key("additionalProperties") { {
obj.insert("additionalProperties".to_string(), Value::Bool(false)); if !obj.contains_key("additionalProperties") {
} obj.insert("additionalProperties".to_string(), Value::Bool(false));
}
// OpenAI API requires non-missing `properties` // OpenAI API requires non-missing `properties`
if !obj.contains_key("properties") { if !obj.contains_key("properties") {
obj.insert("properties".to_string(), Value::Object(Default::default())); obj.insert("properties".to_string(), Value::Object(Default::default()));
}
} }
} }
Ok(()) Ok(())
@ -59,10 +59,10 @@ fn adapt_to_json_schema_subset(json: &mut Value) -> Result<()> {
("optional", |value| value.is_boolean()), ("optional", |value| value.is_boolean()),
]; ];
for (key, predicate) in KEYS_TO_REMOVE { for (key, predicate) in KEYS_TO_REMOVE {
if let Some(value) = obj.get(key) { if let Some(value) = obj.get(key)
if predicate(value) { && predicate(value)
obj.remove(key); {
} obj.remove(key);
} }
} }
@ -77,12 +77,12 @@ fn adapt_to_json_schema_subset(json: &mut Value) -> Result<()> {
} }
// Handle oneOf -> anyOf conversion // Handle oneOf -> anyOf conversion
if let Some(subschemas) = obj.get_mut("oneOf") { if let Some(subschemas) = obj.get_mut("oneOf")
if subschemas.is_array() { && subschemas.is_array()
let subschemas_clone = subschemas.clone(); {
obj.remove("oneOf"); let subschemas_clone = subschemas.clone();
obj.insert("anyOf".to_string(), subschemas_clone); obj.remove("oneOf");
} obj.insert("anyOf".to_string(), subschemas_clone);
} }
// Recursively process all nested objects and arrays // Recursively process all nested objects and arrays

View file

@ -672,29 +672,30 @@ impl EditAgent {
cx: &mut AsyncApp, cx: &mut AsyncApp,
) -> Result<BoxStream<'static, Result<String, LanguageModelCompletionError>>> { ) -> Result<BoxStream<'static, Result<String, LanguageModelCompletionError>>> {
let mut messages_iter = conversation.messages.iter_mut(); let mut messages_iter = conversation.messages.iter_mut();
if let Some(last_message) = messages_iter.next_back() { if let Some(last_message) = messages_iter.next_back()
if last_message.role == Role::Assistant { && last_message.role == Role::Assistant
let old_content_len = last_message.content.len(); {
last_message let old_content_len = last_message.content.len();
.content last_message
.retain(|content| !matches!(content, MessageContent::ToolUse(_))); .content
let new_content_len = last_message.content.len(); .retain(|content| !matches!(content, MessageContent::ToolUse(_)));
let new_content_len = last_message.content.len();
// We just removed pending tool uses from the content of the // We just removed pending tool uses from the content of the
// last message, so it doesn't make sense to cache it anymore // last message, so it doesn't make sense to cache it anymore
// (e.g., the message will look very different on the next // (e.g., the message will look very different on the next
// request). Thus, we move the flag to the message prior to it, // request). Thus, we move the flag to the message prior to it,
// as it will still be a valid prefix of the conversation. // as it will still be a valid prefix of the conversation.
if old_content_len != new_content_len && last_message.cache { if old_content_len != new_content_len
if let Some(prev_message) = messages_iter.next_back() { && last_message.cache
last_message.cache = false; && let Some(prev_message) = messages_iter.next_back()
prev_message.cache = true; {
} last_message.cache = false;
} prev_message.cache = true;
}
if last_message.content.is_empty() { if last_message.content.is_empty() {
conversation.messages.pop(); conversation.messages.pop();
}
} }
} }

View file

@ -1283,14 +1283,14 @@ impl EvalAssertion {
// Parse the score from the response // Parse the score from the response
let re = regex::Regex::new(r"<score>(\d+)</score>").unwrap(); let re = regex::Regex::new(r"<score>(\d+)</score>").unwrap();
if let Some(captures) = re.captures(&output) { if let Some(captures) = re.captures(&output)
if let Some(score_match) = captures.get(1) { && let Some(score_match) = captures.get(1)
let score = score_match.as_str().parse().unwrap_or(0); {
return Ok(EvalAssertionOutcome { let score = score_match.as_str().parse().unwrap_or(0);
score, return Ok(EvalAssertionOutcome {
message: Some(output), score,
}); message: Some(output),
} });
} }
anyhow::bail!("No score found in response. Raw output: {output}"); anyhow::bail!("No score found in response. Raw output: {output}");

View file

@ -155,10 +155,10 @@ impl Tool for EditFileTool {
// It's also possible that the global config dir is configured to be inside the project, // It's also possible that the global config dir is configured to be inside the project,
// so check for that edge case too. // so check for that edge case too.
if let Ok(canonical_path) = std::fs::canonicalize(&input.path) { if let Ok(canonical_path) = std::fs::canonicalize(&input.path)
if canonical_path.starts_with(paths::config_dir()) { && canonical_path.starts_with(paths::config_dir())
return true; {
} return true;
} }
// Check if path is inside the global config directory // Check if path is inside the global config directory
@ -199,10 +199,10 @@ impl Tool for EditFileTool {
.any(|c| c.as_os_str() == local_settings_folder.as_os_str()) .any(|c| c.as_os_str() == local_settings_folder.as_os_str())
{ {
description.push_str(" (local settings)"); description.push_str(" (local settings)");
} else if let Ok(canonical_path) = std::fs::canonicalize(&input.path) { } else if let Ok(canonical_path) = std::fs::canonicalize(&input.path)
if canonical_path.starts_with(paths::config_dir()) { && canonical_path.starts_with(paths::config_dir())
description.push_str(" (global settings)"); {
} description.push_str(" (global settings)");
} }
description description

View file

@ -188,15 +188,14 @@ impl Tool for GrepTool {
// Check if this file should be excluded based on its worktree settings // Check if this file should be excluded based on its worktree settings
if let Ok(Some(project_path)) = project.read_with(cx, |project, cx| { if let Ok(Some(project_path)) = project.read_with(cx, |project, cx| {
project.find_project_path(&path, cx) project.find_project_path(&path, cx)
}) { })
if cx.update(|cx| { && cx.update(|cx| {
let worktree_settings = WorktreeSettings::get(Some((&project_path).into()), cx); let worktree_settings = WorktreeSettings::get(Some((&project_path).into()), cx);
worktree_settings.is_path_excluded(&project_path.path) worktree_settings.is_path_excluded(&project_path.path)
|| worktree_settings.is_path_private(&project_path.path) || worktree_settings.is_path_private(&project_path.path)
}).unwrap_or(false) { }).unwrap_or(false) {
continue; continue;
} }
}
while *parse_status.borrow() != ParseStatus::Idle { while *parse_status.borrow() != ParseStatus::Idle {
parse_status.changed().await?; parse_status.changed().await?;
@ -284,12 +283,11 @@ impl Tool for GrepTool {
output.extend(snapshot.text_for_range(range)); output.extend(snapshot.text_for_range(range));
output.push_str("\n```\n"); output.push_str("\n```\n");
if let Some(ancestor_range) = ancestor_range { if let Some(ancestor_range) = ancestor_range
if end_row < ancestor_range.end.row { && end_row < ancestor_range.end.row {
let remaining_lines = ancestor_range.end.row - end_row; let remaining_lines = ancestor_range.end.row - end_row;
writeln!(output, "\n{} lines remaining in ancestor node. Read the file to see all.", remaining_lines)?; writeln!(output, "\n{} lines remaining in ancestor node. Read the file to see all.", remaining_lines)?;
} }
}
matches_found += 1; matches_found += 1;
} }

View file

@ -43,12 +43,11 @@ impl Transform for ToJsonSchemaSubsetTransform {
fn transform(&mut self, schema: &mut Schema) { fn transform(&mut self, schema: &mut Schema) {
// Ensure that the type field is not an array, this happens when we use // Ensure that the type field is not an array, this happens when we use
// Option<T>, the type will be [T, "null"]. // Option<T>, the type will be [T, "null"].
if let Some(type_field) = schema.get_mut("type") { if let Some(type_field) = schema.get_mut("type")
if let Some(types) = type_field.as_array() { && let Some(types) = type_field.as_array()
if let Some(first_type) = types.first() { && let Some(first_type) = types.first()
*type_field = first_type.clone(); {
} *type_field = first_type.clone();
}
} }
// oneOf is not supported, use anyOf instead // oneOf is not supported, use anyOf instead

View file

@ -186,11 +186,11 @@ unsafe extern "system" fn wnd_proc(
}), }),
WM_TERMINATE => { WM_TERMINATE => {
with_dialog_data(hwnd, |data| { with_dialog_data(hwnd, |data| {
if let Ok(result) = data.borrow_mut().rx.recv() { if let Ok(result) = data.borrow_mut().rx.recv()
if let Err(e) = result { && let Err(e) = result
log::error!("Failed to update Zed: {:?}", e); {
show_error(format!("Error: {:?}", e)); log::error!("Failed to update Zed: {:?}", e);
} show_error(format!("Error: {:?}", e));
} }
}); });
unsafe { PostQuitMessage(0) }; unsafe { PostQuitMessage(0) };

View file

@ -82,11 +82,12 @@ impl Render for Breadcrumbs {
} }
text_style.color = Color::Muted.color(cx); text_style.color = Color::Muted.color(cx);
if index == 0 && !TabBarSettings::get_global(cx).show && active_item.is_dirty(cx) { if index == 0
if let Some(styled_element) = apply_dirty_filename_style(&segment, &text_style, cx) && !TabBarSettings::get_global(cx).show
{ && active_item.is_dirty(cx)
return styled_element; && let Some(styled_element) = apply_dirty_filename_style(&segment, &text_style, cx)
} {
return styled_element;
} }
StyledText::new(segment.text.replace('\n', "")) StyledText::new(segment.text.replace('\n', ""))

View file

@ -572,14 +572,14 @@ impl BufferDiffInner {
pending_range.end.column = 0; pending_range.end.column = 0;
} }
if pending_range == (start_point..end_point) { if pending_range == (start_point..end_point)
if !buffer.has_edits_since_in_range( && !buffer.has_edits_since_in_range(
&pending_hunk.buffer_version, &pending_hunk.buffer_version,
start_anchor..end_anchor, start_anchor..end_anchor,
) { )
has_pending = true; {
secondary_status = pending_hunk.new_status; has_pending = true;
} secondary_status = pending_hunk.new_status;
} }
} }
@ -1036,16 +1036,15 @@ impl BufferDiff {
_ => (true, Some(text::Anchor::MIN..text::Anchor::MAX)), _ => (true, Some(text::Anchor::MIN..text::Anchor::MAX)),
}; };
if let Some(secondary_changed_range) = secondary_diff_change { if let Some(secondary_changed_range) = secondary_diff_change
if let Some(secondary_hunk_range) = && let Some(secondary_hunk_range) =
self.range_to_hunk_range(secondary_changed_range, buffer, cx) self.range_to_hunk_range(secondary_changed_range, buffer, cx)
{ {
if let Some(range) = &mut changed_range { if let Some(range) = &mut changed_range {
range.start = secondary_hunk_range.start.min(&range.start, buffer); range.start = secondary_hunk_range.start.min(&range.start, buffer);
range.end = secondary_hunk_range.end.max(&range.end, buffer); range.end = secondary_hunk_range.end.max(&range.end, buffer);
} else { } else {
changed_range = Some(secondary_hunk_range); changed_range = Some(secondary_hunk_range);
}
} }
} }

View file

@ -827,24 +827,23 @@ impl Room {
); );
Audio::play_sound(Sound::Joined, cx); Audio::play_sound(Sound::Joined, cx);
if let Some(livekit_participants) = &livekit_participants { if let Some(livekit_participants) = &livekit_participants
if let Some(livekit_participant) = livekit_participants && let Some(livekit_participant) = livekit_participants
.get(&ParticipantIdentity(user.id.to_string())) .get(&ParticipantIdentity(user.id.to_string()))
{
for publication in
livekit_participant.track_publications().into_values()
{ {
for publication in if let Some(track) = publication.track() {
livekit_participant.track_publications().into_values() this.livekit_room_updated(
{ RoomEvent::TrackSubscribed {
if let Some(track) = publication.track() { track,
this.livekit_room_updated( publication,
RoomEvent::TrackSubscribed { participant: livekit_participant.clone(),
track, },
publication, cx,
participant: livekit_participant.clone(), )
}, .warn_on_err();
cx,
)
.warn_on_err();
}
} }
} }
} }
@ -940,10 +939,9 @@ impl Room {
self.client.user_id() self.client.user_id()
) )
})?; })?;
if self.live_kit.as_ref().map_or(true, |kit| kit.deafened) { if self.live_kit.as_ref().map_or(true, |kit| kit.deafened) && publication.is_audio()
if publication.is_audio() { {
publication.set_enabled(false, cx); publication.set_enabled(false, cx);
}
} }
match track { match track {
livekit_client::RemoteTrack::Audio(track) => { livekit_client::RemoteTrack::Audio(track) => {
@ -1005,10 +1003,10 @@ impl Room {
for (sid, participant) in &mut self.remote_participants { for (sid, participant) in &mut self.remote_participants {
participant.speaking = speaker_ids.binary_search(sid).is_ok(); participant.speaking = speaker_ids.binary_search(sid).is_ok();
} }
if let Some(id) = self.client.user_id() { if let Some(id) = self.client.user_id()
if let Some(room) = &mut self.live_kit { && let Some(room) = &mut self.live_kit
room.speaking = speaker_ids.binary_search(&id).is_ok(); {
} room.speaking = speaker_ids.binary_search(&id).is_ok();
} }
} }
@ -1042,18 +1040,16 @@ impl Room {
if let LocalTrack::Published { if let LocalTrack::Published {
track_publication, .. track_publication, ..
} = &room.microphone_track } = &room.microphone_track
&& track_publication.sid() == publication.sid()
{ {
if track_publication.sid() == publication.sid() { room.microphone_track = LocalTrack::None;
room.microphone_track = LocalTrack::None;
}
} }
if let LocalTrack::Published { if let LocalTrack::Published {
track_publication, .. track_publication, ..
} = &room.screen_track } = &room.screen_track
&& track_publication.sid() == publication.sid()
{ {
if track_publication.sid() == publication.sid() { room.screen_track = LocalTrack::None;
room.screen_track = LocalTrack::None;
}
} }
} }
} }
@ -1484,10 +1480,8 @@ impl Room {
self.set_deafened(deafened, cx); self.set_deafened(deafened, cx);
if should_change_mute { if should_change_mute && let Some(task) = self.set_mute(deafened, cx) {
if let Some(task) = self.set_mute(deafened, cx) { task.detach_and_log_err(cx);
task.detach_and_log_err(cx);
}
} }
} }
} }

View file

@ -191,12 +191,11 @@ impl ChannelBuffer {
operation, operation,
is_local: true, is_local: true,
} => { } => {
if *ZED_ALWAYS_ACTIVE { if *ZED_ALWAYS_ACTIVE
if let language::Operation::UpdateSelections { selections, .. } = operation { && let language::Operation::UpdateSelections { selections, .. } = operation
if selections.is_empty() { && selections.is_empty()
return; {
} return;
}
} }
let operation = language::proto::serialize_operation(operation); let operation = language::proto::serialize_operation(operation);
self.client self.client

View file

@ -329,24 +329,24 @@ impl ChannelChat {
loop { loop {
let step = chat let step = chat
.update(&mut cx, |chat, cx| { .update(&mut cx, |chat, cx| {
if let Some(first_id) = chat.first_loaded_message_id() { if let Some(first_id) = chat.first_loaded_message_id()
if first_id <= message_id { && first_id <= message_id
let mut cursor = chat {
.messages let mut cursor = chat
.cursor::<Dimensions<ChannelMessageId, Count>>(&()); .messages
let message_id = ChannelMessageId::Saved(message_id); .cursor::<Dimensions<ChannelMessageId, Count>>(&());
cursor.seek(&message_id, Bias::Left); let message_id = ChannelMessageId::Saved(message_id);
return ControlFlow::Break( cursor.seek(&message_id, Bias::Left);
if cursor return ControlFlow::Break(
.item() if cursor
.map_or(false, |message| message.id == message_id) .item()
{ .map_or(false, |message| message.id == message_id)
Some(cursor.start().1.0) {
} else { Some(cursor.start().1.0)
None } else {
}, None
); },
} );
} }
ControlFlow::Continue(chat.load_more_messages(cx)) ControlFlow::Continue(chat.load_more_messages(cx))
}) })
@ -359,22 +359,21 @@ impl ChannelChat {
} }
pub fn acknowledge_last_message(&mut self, cx: &mut Context<Self>) { pub fn acknowledge_last_message(&mut self, cx: &mut Context<Self>) {
if let ChannelMessageId::Saved(latest_message_id) = self.messages.summary().max_id { if let ChannelMessageId::Saved(latest_message_id) = self.messages.summary().max_id
if self && self
.last_acknowledged_id .last_acknowledged_id
.map_or(true, |acknowledged_id| acknowledged_id < latest_message_id) .map_or(true, |acknowledged_id| acknowledged_id < latest_message_id)
{ {
self.rpc self.rpc
.send(proto::AckChannelMessage { .send(proto::AckChannelMessage {
channel_id: self.channel_id.0, channel_id: self.channel_id.0,
message_id: latest_message_id, message_id: latest_message_id,
}) })
.ok(); .ok();
self.last_acknowledged_id = Some(latest_message_id); self.last_acknowledged_id = Some(latest_message_id);
self.channel_store.update(cx, |store, cx| { self.channel_store.update(cx, |store, cx| {
store.acknowledge_message_id(self.channel_id, latest_message_id, cx); store.acknowledge_message_id(self.channel_id, latest_message_id, cx);
}); });
}
} }
} }
@ -407,10 +406,10 @@ impl ChannelChat {
let missing_ancestors = loaded_messages let missing_ancestors = loaded_messages
.iter() .iter()
.filter_map(|message| { .filter_map(|message| {
if let Some(ancestor_id) = message.reply_to_message_id { if let Some(ancestor_id) = message.reply_to_message_id
if !loaded_message_ids.contains(&ancestor_id) { && !loaded_message_ids.contains(&ancestor_id)
return Some(ancestor_id); {
} return Some(ancestor_id);
} }
None None
}) })
@ -646,32 +645,32 @@ impl ChannelChat {
fn message_removed(&mut self, id: u64, cx: &mut Context<Self>) { fn message_removed(&mut self, id: u64, cx: &mut Context<Self>) {
let mut cursor = self.messages.cursor::<ChannelMessageId>(&()); let mut cursor = self.messages.cursor::<ChannelMessageId>(&());
let mut messages = cursor.slice(&ChannelMessageId::Saved(id), Bias::Left); let mut messages = cursor.slice(&ChannelMessageId::Saved(id), Bias::Left);
if let Some(item) = cursor.item() { if let Some(item) = cursor.item()
if item.id == ChannelMessageId::Saved(id) { && item.id == ChannelMessageId::Saved(id)
let deleted_message_ix = messages.summary().count; {
cursor.next(); let deleted_message_ix = messages.summary().count;
messages.append(cursor.suffix(), &()); cursor.next();
drop(cursor); messages.append(cursor.suffix(), &());
self.messages = messages; drop(cursor);
self.messages = messages;
// If the message that was deleted was the last acknowledged message, // If the message that was deleted was the last acknowledged message,
// replace the acknowledged message with an earlier one. // replace the acknowledged message with an earlier one.
self.channel_store.update(cx, |store, _| { self.channel_store.update(cx, |store, _| {
let summary = self.messages.summary(); let summary = self.messages.summary();
if summary.count == 0 { if summary.count == 0 {
store.set_acknowledged_message_id(self.channel_id, None); store.set_acknowledged_message_id(self.channel_id, None);
} else if deleted_message_ix == summary.count { } else if deleted_message_ix == summary.count
if let ChannelMessageId::Saved(id) = summary.max_id { && let ChannelMessageId::Saved(id) = summary.max_id
store.set_acknowledged_message_id(self.channel_id, Some(id)); {
} store.set_acknowledged_message_id(self.channel_id, Some(id));
} }
}); });
cx.emit(ChannelChatEvent::MessagesUpdated { cx.emit(ChannelChatEvent::MessagesUpdated {
old_range: deleted_message_ix..deleted_message_ix + 1, old_range: deleted_message_ix..deleted_message_ix + 1,
new_count: 0, new_count: 0,
}); });
}
} }
} }

View file

@ -262,13 +262,12 @@ impl ChannelStore {
} }
} }
status = status_receiver.next().fuse() => { status = status_receiver.next().fuse() => {
if let Some(status) = status { if let Some(status) = status
if status.is_connected() { && status.is_connected() {
this.update(cx, |this, _cx| { this.update(cx, |this, _cx| {
this.initialize(); this.initialize();
}).ok(); }).ok();
} }
}
continue; continue;
} }
_ = timer => { _ = timer => {
@ -336,10 +335,10 @@ impl ChannelStore {
} }
pub fn has_open_channel_buffer(&self, channel_id: ChannelId, _cx: &App) -> bool { pub fn has_open_channel_buffer(&self, channel_id: ChannelId, _cx: &App) -> bool {
if let Some(buffer) = self.opened_buffers.get(&channel_id) { if let Some(buffer) = self.opened_buffers.get(&channel_id)
if let OpenEntityHandle::Open(buffer) = buffer { && let OpenEntityHandle::Open(buffer) = buffer
return buffer.upgrade().is_some(); {
} return buffer.upgrade().is_some();
} }
false false
} }
@ -408,13 +407,12 @@ impl ChannelStore {
pub fn last_acknowledge_message_id(&self, channel_id: ChannelId) -> Option<u64> { pub fn last_acknowledge_message_id(&self, channel_id: ChannelId) -> Option<u64> {
self.channel_states.get(&channel_id).and_then(|state| { self.channel_states.get(&channel_id).and_then(|state| {
if let Some(last_message_id) = state.latest_chat_message { if let Some(last_message_id) = state.latest_chat_message
if state && state
.last_acknowledged_message_id() .last_acknowledged_message_id()
.is_some_and(|id| id < last_message_id) .is_some_and(|id| id < last_message_id)
{ {
return state.last_acknowledged_message_id(); return state.last_acknowledged_message_id();
}
} }
None None
@ -962,27 +960,27 @@ impl ChannelStore {
self.disconnect_channel_buffers_task.take(); self.disconnect_channel_buffers_task.take();
for chat in self.opened_chats.values() { for chat in self.opened_chats.values() {
if let OpenEntityHandle::Open(chat) = chat { if let OpenEntityHandle::Open(chat) = chat
if let Some(chat) = chat.upgrade() { && let Some(chat) = chat.upgrade()
chat.update(cx, |chat, cx| { {
chat.rejoin(cx); chat.update(cx, |chat, cx| {
}); chat.rejoin(cx);
} });
} }
} }
let mut buffer_versions = Vec::new(); let mut buffer_versions = Vec::new();
for buffer in self.opened_buffers.values() { for buffer in self.opened_buffers.values() {
if let OpenEntityHandle::Open(buffer) = buffer { if let OpenEntityHandle::Open(buffer) = buffer
if let Some(buffer) = buffer.upgrade() { && let Some(buffer) = buffer.upgrade()
let channel_buffer = buffer.read(cx); {
let buffer = channel_buffer.buffer().read(cx); let channel_buffer = buffer.read(cx);
buffer_versions.push(proto::ChannelBufferVersion { let buffer = channel_buffer.buffer().read(cx);
channel_id: channel_buffer.channel_id.0, buffer_versions.push(proto::ChannelBufferVersion {
epoch: channel_buffer.epoch(), channel_id: channel_buffer.channel_id.0,
version: language::proto::serialize_version(&buffer.version()), epoch: channel_buffer.epoch(),
}); version: language::proto::serialize_version(&buffer.version()),
} });
} }
} }
@ -1078,10 +1076,10 @@ impl ChannelStore {
if let Some(this) = this.upgrade() { if let Some(this) = this.upgrade() {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
for (_, buffer) in &this.opened_buffers { for (_, buffer) in &this.opened_buffers {
if let OpenEntityHandle::Open(buffer) = &buffer { if let OpenEntityHandle::Open(buffer) = &buffer
if let Some(buffer) = buffer.upgrade() { && let Some(buffer) = buffer.upgrade()
buffer.update(cx, |buffer, cx| buffer.disconnect(cx)); {
} buffer.update(cx, |buffer, cx| buffer.disconnect(cx));
} }
} }
}) })
@ -1157,10 +1155,9 @@ impl ChannelStore {
} }
if let Some(OpenEntityHandle::Open(buffer)) = if let Some(OpenEntityHandle::Open(buffer)) =
self.opened_buffers.remove(&channel_id) self.opened_buffers.remove(&channel_id)
&& let Some(buffer) = buffer.upgrade()
{ {
if let Some(buffer) = buffer.upgrade() { buffer.update(cx, ChannelBuffer::disconnect);
buffer.update(cx, ChannelBuffer::disconnect);
}
} }
} }
} }
@ -1170,12 +1167,11 @@ impl ChannelStore {
let id = ChannelId(channel.id); let id = ChannelId(channel.id);
let channel_changed = index.insert(channel); let channel_changed = index.insert(channel);
if channel_changed { if channel_changed
if let Some(OpenEntityHandle::Open(buffer)) = self.opened_buffers.get(&id) { && let Some(OpenEntityHandle::Open(buffer)) = self.opened_buffers.get(&id)
if let Some(buffer) = buffer.upgrade() { && let Some(buffer) = buffer.upgrade()
buffer.update(cx, ChannelBuffer::channel_changed); {
} buffer.update(cx, ChannelBuffer::channel_changed);
}
} }
} }

View file

@ -587,13 +587,10 @@ mod flatpak {
pub fn set_bin_if_no_escape(mut args: super::Args) -> super::Args { pub fn set_bin_if_no_escape(mut args: super::Args) -> super::Args {
if env::var(NO_ESCAPE_ENV_NAME).is_ok() if env::var(NO_ESCAPE_ENV_NAME).is_ok()
&& env::var("FLATPAK_ID").map_or(false, |id| id.starts_with("dev.zed.Zed")) && env::var("FLATPAK_ID").map_or(false, |id| id.starts_with("dev.zed.Zed"))
&& args.zed.is_none()
{ {
if args.zed.is_none() { args.zed = Some("/app/libexec/zed-editor".into());
args.zed = Some("/app/libexec/zed-editor".into()); unsafe { env::set_var("ZED_UPDATE_EXPLANATION", "Please use flatpak to update zed") };
unsafe {
env::set_var("ZED_UPDATE_EXPLANATION", "Please use flatpak to update zed")
};
}
} }
args args
} }

View file

@ -864,22 +864,23 @@ impl Client {
let mut credentials = None; let mut credentials = None;
let old_credentials = self.state.read().credentials.clone(); let old_credentials = self.state.read().credentials.clone();
if let Some(old_credentials) = old_credentials { if let Some(old_credentials) = old_credentials
if self.validate_credentials(&old_credentials, cx).await? { && self.validate_credentials(&old_credentials, cx).await?
credentials = Some(old_credentials); {
} credentials = Some(old_credentials);
} }
if credentials.is_none() && try_provider { if credentials.is_none()
if let Some(stored_credentials) = self.credentials_provider.read_credentials(cx).await { && try_provider
if self.validate_credentials(&stored_credentials, cx).await? { && let Some(stored_credentials) = self.credentials_provider.read_credentials(cx).await
credentials = Some(stored_credentials); {
} else { if self.validate_credentials(&stored_credentials, cx).await? {
self.credentials_provider credentials = Some(stored_credentials);
.delete_credentials(cx) } else {
.await self.credentials_provider
.log_err(); .delete_credentials(cx)
} .await
.log_err();
} }
} }

View file

@ -894,10 +894,10 @@ impl UserStore {
let mut ret = Vec::with_capacity(users.len()); let mut ret = Vec::with_capacity(users.len());
for user in users { for user in users {
let user = User::new(user); let user = User::new(user);
if let Some(old) = self.users.insert(user.id, user.clone()) { if let Some(old) = self.users.insert(user.id, user.clone())
if old.github_login != user.github_login { && old.github_login != user.github_login
self.by_github_login.remove(&old.github_login); {
} self.by_github_login.remove(&old.github_login);
} }
self.by_github_login self.by_github_login
.insert(user.github_login.clone(), user.id); .insert(user.github_login.clone(), user.id);

View file

@ -149,35 +149,35 @@ pub async fn post_crash(
"crash report" "crash report"
); );
if let Some(kinesis_client) = app.kinesis_client.clone() { if let Some(kinesis_client) = app.kinesis_client.clone()
if let Some(stream) = app.config.kinesis_stream.clone() { && let Some(stream) = app.config.kinesis_stream.clone()
let properties = json!({ {
"app_version": report.header.app_version, let properties = json!({
"os_version": report.header.os_version, "app_version": report.header.app_version,
"os_name": "macOS", "os_version": report.header.os_version,
"bundle_id": report.header.bundle_id, "os_name": "macOS",
"incident_id": report.header.incident_id, "bundle_id": report.header.bundle_id,
"installation_id": installation_id, "incident_id": report.header.incident_id,
"description": description, "installation_id": installation_id,
"backtrace": summary, "description": description,
}); "backtrace": summary,
let row = SnowflakeRow::new( });
"Crash Reported", let row = SnowflakeRow::new(
None, "Crash Reported",
false, None,
Some(installation_id), false,
properties, Some(installation_id),
); properties,
let data = serde_json::to_vec(&row)?; );
kinesis_client let data = serde_json::to_vec(&row)?;
.put_record() kinesis_client
.stream_name(stream) .put_record()
.partition_key(row.insert_id.unwrap_or_default()) .stream_name(stream)
.data(data.into()) .partition_key(row.insert_id.unwrap_or_default())
.send() .data(data.into())
.await .send()
.log_err(); .await
} .log_err();
} }
if let Some(slack_panics_webhook) = app.config.slack_panics_webhook.clone() { if let Some(slack_panics_webhook) = app.config.slack_panics_webhook.clone() {
@ -359,34 +359,34 @@ pub async fn post_panic(
"panic report" "panic report"
); );
if let Some(kinesis_client) = app.kinesis_client.clone() { if let Some(kinesis_client) = app.kinesis_client.clone()
if let Some(stream) = app.config.kinesis_stream.clone() { && let Some(stream) = app.config.kinesis_stream.clone()
let properties = json!({ {
"app_version": panic.app_version, let properties = json!({
"os_name": panic.os_name, "app_version": panic.app_version,
"os_version": panic.os_version, "os_name": panic.os_name,
"incident_id": incident_id, "os_version": panic.os_version,
"installation_id": panic.installation_id, "incident_id": incident_id,
"description": panic.payload, "installation_id": panic.installation_id,
"backtrace": backtrace, "description": panic.payload,
}); "backtrace": backtrace,
let row = SnowflakeRow::new( });
"Panic Reported", let row = SnowflakeRow::new(
None, "Panic Reported",
false, None,
panic.installation_id.clone(), false,
properties, panic.installation_id.clone(),
); properties,
let data = serde_json::to_vec(&row)?; );
kinesis_client let data = serde_json::to_vec(&row)?;
.put_record() kinesis_client
.stream_name(stream) .put_record()
.partition_key(row.insert_id.unwrap_or_default()) .stream_name(stream)
.data(data.into()) .partition_key(row.insert_id.unwrap_or_default())
.send() .data(data.into())
.await .send()
.log_err(); .await
} .log_err();
} }
if !report_to_slack(&panic) { if !report_to_slack(&panic) {
@ -518,31 +518,31 @@ pub async fn post_events(
let first_event_at = chrono::Utc::now() let first_event_at = chrono::Utc::now()
- chrono::Duration::milliseconds(last_event.milliseconds_since_first_event); - chrono::Duration::milliseconds(last_event.milliseconds_since_first_event);
if let Some(kinesis_client) = app.kinesis_client.clone() { if let Some(kinesis_client) = app.kinesis_client.clone()
if let Some(stream) = app.config.kinesis_stream.clone() { && let Some(stream) = app.config.kinesis_stream.clone()
let mut request = kinesis_client.put_records().stream_name(stream); {
let mut has_records = false; let mut request = kinesis_client.put_records().stream_name(stream);
for row in for_snowflake( let mut has_records = false;
request_body.clone(), for row in for_snowflake(
first_event_at, request_body.clone(),
country_code.clone(), first_event_at,
checksum_matched, country_code.clone(),
) { checksum_matched,
if let Some(data) = serde_json::to_vec(&row).log_err() { ) {
request = request.records( if let Some(data) = serde_json::to_vec(&row).log_err() {
aws_sdk_kinesis::types::PutRecordsRequestEntry::builder() request = request.records(
.partition_key(request_body.system_id.clone().unwrap_or_default()) aws_sdk_kinesis::types::PutRecordsRequestEntry::builder()
.data(data.into()) .partition_key(request_body.system_id.clone().unwrap_or_default())
.build() .data(data.into())
.unwrap(), .build()
); .unwrap(),
has_records = true; );
} has_records = true;
}
if has_records {
request.send().await.log_err();
} }
} }
if has_records {
request.send().await.log_err();
}
}; };
Ok(()) Ok(())

View file

@ -337,8 +337,7 @@ async fn fetch_extensions_from_blob_store(
if known_versions if known_versions
.binary_search_by_key(&published_version, |known_version| known_version) .binary_search_by_key(&published_version, |known_version| known_version)
.is_err() .is_err()
{ && let Some(extension) = fetch_extension_manifest(
if let Some(extension) = fetch_extension_manifest(
blob_store_client, blob_store_client,
blob_store_bucket, blob_store_bucket,
extension_id, extension_id,
@ -346,12 +345,11 @@ async fn fetch_extensions_from_blob_store(
) )
.await .await
.log_err() .log_err()
{ {
new_versions new_versions
.entry(extension_id) .entry(extension_id)
.or_default() .or_default()
.push(extension); .push(extension);
}
} }
} }
} }

View file

@ -79,27 +79,27 @@ pub async fn validate_header<B>(mut req: Request<B>, next: Next<B>) -> impl Into
verify_access_token(access_token, user_id, &state.db).await verify_access_token(access_token, user_id, &state.db).await
}; };
if let Ok(validate_result) = validate_result { if let Ok(validate_result) = validate_result
if validate_result.is_valid { && validate_result.is_valid
let user = state {
.db let user = state
.get_user_by_id(user_id) .db
.await? .get_user_by_id(user_id)
.with_context(|| format!("user {user_id} not found"))?; .await?
.with_context(|| format!("user {user_id} not found"))?;
if let Some(impersonator_id) = validate_result.impersonator_id { if let Some(impersonator_id) = validate_result.impersonator_id {
let admin = state let admin = state
.db .db
.get_user_by_id(impersonator_id) .get_user_by_id(impersonator_id)
.await? .await?
.with_context(|| format!("user {impersonator_id} not found"))?; .with_context(|| format!("user {impersonator_id} not found"))?;
req.extensions_mut() req.extensions_mut()
.insert(Principal::Impersonated { user, admin }); .insert(Principal::Impersonated { user, admin });
} else { } else {
req.extensions_mut().insert(Principal::User(user)); req.extensions_mut().insert(Principal::User(user));
}; };
return Ok::<_, Error>(next.run(req).await); return Ok::<_, Error>(next.run(req).await);
}
} }
Err(Error::http( Err(Error::http(

View file

@ -87,10 +87,10 @@ impl Database {
continue; continue;
}; };
if let Some((_, max_extension_version)) = &max_versions.get(&version.extension_id) { if let Some((_, max_extension_version)) = &max_versions.get(&version.extension_id)
if max_extension_version > &extension_version { && max_extension_version > &extension_version
continue; {
} continue;
} }
if let Some(constraints) = constraints { if let Some(constraints) = constraints {
@ -331,10 +331,10 @@ impl Database {
.exec_without_returning(&*tx) .exec_without_returning(&*tx)
.await?; .await?;
if let Ok(db_version) = semver::Version::parse(&extension.latest_version) { if let Ok(db_version) = semver::Version::parse(&extension.latest_version)
if db_version >= latest_version.version { && db_version >= latest_version.version
continue; {
} continue;
} }
let mut extension = extension.into_active_model(); let mut extension = extension.into_active_model();

View file

@ -1321,10 +1321,10 @@ impl Database {
.await?; .await?;
let mut connection_ids = HashSet::default(); let mut connection_ids = HashSet::default();
if let Some(host_connection) = project.host_connection().log_err() { if let Some(host_connection) = project.host_connection().log_err()
if !exclude_dev_server { && !exclude_dev_server
connection_ids.insert(host_connection); {
} connection_ids.insert(host_connection);
} }
while let Some(collaborator) = collaborators.next().await { while let Some(collaborator) = collaborators.next().await {

View file

@ -616,10 +616,10 @@ impl Server {
} }
} }
if let Some(live_kit) = livekit_client.as_ref() { if let Some(live_kit) = livekit_client.as_ref()
if delete_livekit_room { && delete_livekit_room
live_kit.delete_room(livekit_room).await.trace_err(); {
} live_kit.delete_room(livekit_room).await.trace_err();
} }
} }
} }
@ -1015,47 +1015,47 @@ impl Server {
inviter_id: UserId, inviter_id: UserId,
invitee_id: UserId, invitee_id: UserId,
) -> Result<()> { ) -> Result<()> {
if let Some(user) = self.app_state.db.get_user_by_id(inviter_id).await? { if let Some(user) = self.app_state.db.get_user_by_id(inviter_id).await?
if let Some(code) = &user.invite_code { && let Some(code) = &user.invite_code
let pool = self.connection_pool.lock(); {
let invitee_contact = contact_for_user(invitee_id, false, &pool); let pool = self.connection_pool.lock();
for connection_id in pool.user_connection_ids(inviter_id) { let invitee_contact = contact_for_user(invitee_id, false, &pool);
self.peer.send( for connection_id in pool.user_connection_ids(inviter_id) {
connection_id, self.peer.send(
proto::UpdateContacts { connection_id,
contacts: vec![invitee_contact.clone()], proto::UpdateContacts {
..Default::default() contacts: vec![invitee_contact.clone()],
}, ..Default::default()
)?; },
self.peer.send( )?;
connection_id, self.peer.send(
proto::UpdateInviteInfo { connection_id,
url: format!("{}{}", self.app_state.config.invite_link_prefix, &code), proto::UpdateInviteInfo {
count: user.invite_count as u32, url: format!("{}{}", self.app_state.config.invite_link_prefix, &code),
}, count: user.invite_count as u32,
)?; },
} )?;
} }
} }
Ok(()) Ok(())
} }
pub async fn invite_count_updated(self: &Arc<Self>, user_id: UserId) -> Result<()> { pub async fn invite_count_updated(self: &Arc<Self>, user_id: UserId) -> Result<()> {
if let Some(user) = self.app_state.db.get_user_by_id(user_id).await? { if let Some(user) = self.app_state.db.get_user_by_id(user_id).await?
if let Some(invite_code) = &user.invite_code { && let Some(invite_code) = &user.invite_code
let pool = self.connection_pool.lock(); {
for connection_id in pool.user_connection_ids(user_id) { let pool = self.connection_pool.lock();
self.peer.send( for connection_id in pool.user_connection_ids(user_id) {
connection_id, self.peer.send(
proto::UpdateInviteInfo { connection_id,
url: format!( proto::UpdateInviteInfo {
"{}{}", url: format!(
self.app_state.config.invite_link_prefix, invite_code "{}{}",
), self.app_state.config.invite_link_prefix, invite_code
count: user.invite_count as u32, ),
}, count: user.invite_count as u32,
)?; },
} )?;
} }
} }
Ok(()) Ok(())
@ -1101,10 +1101,10 @@ fn broadcast<F>(
F: FnMut(ConnectionId) -> anyhow::Result<()>, F: FnMut(ConnectionId) -> anyhow::Result<()>,
{ {
for receiver_id in receiver_ids { for receiver_id in receiver_ids {
if Some(receiver_id) != sender_id { if Some(receiver_id) != sender_id
if let Err(error) = f(receiver_id) { && let Err(error) = f(receiver_id)
tracing::error!("failed to send to {:?} {}", receiver_id, error); {
} tracing::error!("failed to send to {:?} {}", receiver_id, error);
} }
} }
} }
@ -2294,11 +2294,10 @@ async fn update_language_server(
let db = session.db().await; let db = session.db().await;
if let Some(proto::update_language_server::Variant::MetadataUpdated(update)) = &request.variant if let Some(proto::update_language_server::Variant::MetadataUpdated(update)) = &request.variant
&& let Some(capabilities) = update.capabilities.clone()
{ {
if let Some(capabilities) = update.capabilities.clone() { db.update_server_capabilities(project_id, request.language_server_id, capabilities)
db.update_server_capabilities(project_id, request.language_server_id, capabilities) .await?;
.await?;
}
} }
let project_connection_ids = db let project_connection_ids = db

View file

@ -1162,8 +1162,8 @@ impl RandomizedTest for ProjectCollaborationTest {
Some((project, cx)) Some((project, cx))
}); });
if !guest_project.is_disconnected(cx) { if !guest_project.is_disconnected(cx)
if let Some((host_project, host_cx)) = host_project { && let Some((host_project, host_cx)) = host_project {
let host_worktree_snapshots = let host_worktree_snapshots =
host_project.read_with(host_cx, |host_project, cx| { host_project.read_with(host_cx, |host_project, cx| {
host_project host_project
@ -1235,7 +1235,6 @@ impl RandomizedTest for ProjectCollaborationTest {
); );
} }
} }
}
for buffer in guest_project.opened_buffers(cx) { for buffer in guest_project.opened_buffers(cx) {
let buffer = buffer.read(cx); let buffer = buffer.read(cx);

View file

@ -198,11 +198,11 @@ pub async fn run_randomized_test<T: RandomizedTest>(
} }
pub fn save_randomized_test_plan() { pub fn save_randomized_test_plan() {
if let Some(serialize_plan) = LAST_PLAN.lock().take() { if let Some(serialize_plan) = LAST_PLAN.lock().take()
if let Some(path) = plan_save_path() { && let Some(path) = plan_save_path()
eprintln!("saved test plan to path {:?}", path); {
std::fs::write(path, serialize_plan()).unwrap(); eprintln!("saved test plan to path {:?}", path);
} std::fs::write(path, serialize_plan()).unwrap();
} }
} }
@ -290,10 +290,9 @@ impl<T: RandomizedTest> TestPlan<T> {
if let StoredOperation::Client { if let StoredOperation::Client {
user_id, batch_id, .. user_id, batch_id, ..
} = operation } = operation
&& batch_id == current_batch_id
{ {
if batch_id == current_batch_id { return Some(user_id);
return Some(user_id);
}
} }
None None
})); }));
@ -366,10 +365,9 @@ impl<T: RandomizedTest> TestPlan<T> {
}, },
applied, applied,
) = stored_operation ) = stored_operation
&& user_id == &current_user_id
{ {
if user_id == &current_user_id { return Some((operation.clone(), applied.clone()));
return Some((operation.clone(), applied.clone()));
}
} }
} }
None None
@ -550,11 +548,11 @@ impl<T: RandomizedTest> TestPlan<T> {
.unwrap(); .unwrap();
let pool = server.connection_pool.lock(); let pool = server.connection_pool.lock();
for contact in contacts { for contact in contacts {
if let db::Contact::Accepted { user_id, busy, .. } = contact { if let db::Contact::Accepted { user_id, busy, .. } = contact
if user_id == removed_user_id { && user_id == removed_user_id
assert!(!pool.is_user_online(user_id)); {
assert!(!busy); assert!(!pool.is_user_online(user_id));
} assert!(!busy);
} }
} }
} }

View file

@ -130,17 +130,17 @@ impl UserBackfiller {
.and_then(|value| value.parse::<i64>().ok()) .and_then(|value| value.parse::<i64>().ok())
.and_then(|value| DateTime::from_timestamp(value, 0)); .and_then(|value| DateTime::from_timestamp(value, 0));
if rate_limit_remaining == Some(0) { if rate_limit_remaining == Some(0)
if let Some(reset_at) = rate_limit_reset { && let Some(reset_at) = rate_limit_reset
let now = Utc::now(); {
if reset_at > now { let now = Utc::now();
let sleep_duration = reset_at - now; if reset_at > now {
log::info!( let sleep_duration = reset_at - now;
"rate limit reached. Sleeping for {} seconds", log::info!(
sleep_duration.num_seconds() "rate limit reached. Sleeping for {} seconds",
); sleep_duration.num_seconds()
self.executor.sleep(sleep_duration.to_std().unwrap()).await; );
} self.executor.sleep(sleep_duration.to_std().unwrap()).await;
} }
} }

View file

@ -107,43 +107,32 @@ impl ChannelView {
.find(|view| view.read(cx).channel_buffer.read(cx).remote_id(cx) == buffer_id); .find(|view| view.read(cx).channel_buffer.read(cx).remote_id(cx) == buffer_id);
// If this channel buffer is already open in this pane, just return it. // If this channel buffer is already open in this pane, just return it.
if let Some(existing_view) = existing_view.clone() { if let Some(existing_view) = existing_view.clone()
if existing_view.read(cx).channel_buffer == channel_view.read(cx).channel_buffer && existing_view.read(cx).channel_buffer == channel_view.read(cx).channel_buffer
{ {
if let Some(link_position) = link_position { if let Some(link_position) = link_position {
existing_view.update(cx, |channel_view, cx| { existing_view.update(cx, |channel_view, cx| {
channel_view.focus_position_from_link( channel_view.focus_position_from_link(link_position, true, window, cx)
link_position, });
true,
window,
cx,
)
});
}
return existing_view;
} }
return existing_view;
} }
// If the pane contained a disconnected view for this channel buffer, // If the pane contained a disconnected view for this channel buffer,
// replace that. // replace that.
if let Some(existing_item) = existing_view { if let Some(existing_item) = existing_view
if let Some(ix) = pane.index_for_item(&existing_item) { && let Some(ix) = pane.index_for_item(&existing_item)
pane.close_item_by_id( {
existing_item.entity_id(), pane.close_item_by_id(existing_item.entity_id(), SaveIntent::Skip, window, cx)
SaveIntent::Skip,
window,
cx,
)
.detach(); .detach();
pane.add_item( pane.add_item(
Box::new(channel_view.clone()), Box::new(channel_view.clone()),
true, true,
true, true,
Some(ix), Some(ix),
window, window,
cx, cx,
); );
}
} }
if let Some(link_position) = link_position { if let Some(link_position) = link_position {
@ -259,26 +248,21 @@ impl ChannelView {
.editor .editor
.update(cx, |editor, cx| editor.snapshot(window, cx)); .update(cx, |editor, cx| editor.snapshot(window, cx));
if let Some(outline) = snapshot.buffer_snapshot.outline(None) { if let Some(outline) = snapshot.buffer_snapshot.outline(None)
if let Some(item) = outline && let Some(item) = outline
.items .items
.iter() .iter()
.find(|item| &Channel::slug(&item.text).to_lowercase() == &position) .find(|item| &Channel::slug(&item.text).to_lowercase() == &position)
{ {
self.editor.update(cx, |editor, cx| { self.editor.update(cx, |editor, cx| {
editor.change_selections( editor.change_selections(
SelectionEffects::scroll(Autoscroll::focused()), SelectionEffects::scroll(Autoscroll::focused()),
window, window,
cx, cx,
|s| { |s| s.replace_cursors_with(|map| vec![item.range.start.to_display_point(map)]),
s.replace_cursors_with(|map| { )
vec![item.range.start.to_display_point(map)] });
}) return;
},
)
});
return;
}
} }
if !first_attempt { if !first_attempt {

View file

@ -287,19 +287,20 @@ impl ChatPanel {
} }
fn acknowledge_last_message(&mut self, cx: &mut Context<Self>) { fn acknowledge_last_message(&mut self, cx: &mut Context<Self>) {
if self.active && self.is_scrolled_to_bottom { if self.active
if let Some((chat, _)) = &self.active_chat { && self.is_scrolled_to_bottom
if let Some(channel_id) = self.channel_id(cx) { && let Some((chat, _)) = &self.active_chat
self.last_acknowledged_message_id = self {
.channel_store if let Some(channel_id) = self.channel_id(cx) {
.read(cx) self.last_acknowledged_message_id = self
.last_acknowledge_message_id(channel_id); .channel_store
} .read(cx)
.last_acknowledge_message_id(channel_id);
chat.update(cx, |chat, cx| {
chat.acknowledge_last_message(cx);
});
} }
chat.update(cx, |chat, cx| {
chat.acknowledge_last_message(cx);
});
} }
} }
@ -405,14 +406,13 @@ impl ChatPanel {
&& last_message.id != this_message.id && last_message.id != this_message.id
&& duration_since_last_message < Duration::from_secs(5 * 60); && duration_since_last_message < Duration::from_secs(5 * 60);
if let ChannelMessageId::Saved(id) = this_message.id { if let ChannelMessageId::Saved(id) = this_message.id
if this_message && this_message
.mentions .mentions
.iter() .iter()
.any(|(_, user_id)| Some(*user_id) == self.client.user_id()) .any(|(_, user_id)| Some(*user_id) == self.client.user_id())
{ {
active_chat.acknowledge_message(id); active_chat.acknowledge_message(id);
}
} }
(this_message, is_continuation_from_previous, is_admin) (this_message, is_continuation_from_previous, is_admin)
@ -871,34 +871,33 @@ impl ChatPanel {
scroll_to_message_id.or(this.last_acknowledged_message_id) scroll_to_message_id.or(this.last_acknowledged_message_id)
})?; })?;
if let Some(message_id) = scroll_to_message_id { if let Some(message_id) = scroll_to_message_id
if let Some(item_ix) = && let Some(item_ix) =
ChannelChat::load_history_since_message(chat.clone(), message_id, cx.clone()) ChannelChat::load_history_since_message(chat.clone(), message_id, cx.clone())
.await .await
{ {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
if let Some(highlight_message_id) = highlight_message_id { if let Some(highlight_message_id) = highlight_message_id {
let task = cx.spawn(async move |this, cx| { let task = cx.spawn(async move |this, cx| {
cx.background_executor().timer(Duration::from_secs(2)).await; cx.background_executor().timer(Duration::from_secs(2)).await;
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.highlighted_message.take(); this.highlighted_message.take();
cx.notify(); cx.notify();
}) })
.ok(); .ok();
}); });
this.highlighted_message = Some((highlight_message_id, task)); this.highlighted_message = Some((highlight_message_id, task));
} }
if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) { if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
this.message_list.scroll_to(ListOffset { this.message_list.scroll_to(ListOffset {
item_ix, item_ix,
offset_in_item: px(0.0), offset_in_item: px(0.0),
}); });
cx.notify(); cx.notify();
} }
})?; })?;
}
} }
Ok(()) Ok(())

View file

@ -241,38 +241,36 @@ impl MessageEditor {
) -> Task<Result<Vec<CompletionResponse>>> { ) -> Task<Result<Vec<CompletionResponse>>> {
if let Some((start_anchor, query, candidates)) = if let Some((start_anchor, query, candidates)) =
self.collect_mention_candidates(buffer, end_anchor, cx) self.collect_mention_candidates(buffer, end_anchor, cx)
&& !candidates.is_empty()
{ {
if !candidates.is_empty() { return cx.spawn(async move |_, cx| {
return cx.spawn(async move |_, cx| { let completion_response = Self::completions_for_candidates(
let completion_response = Self::completions_for_candidates( cx,
cx, query.as_str(),
query.as_str(), &candidates,
&candidates, start_anchor..end_anchor,
start_anchor..end_anchor, Self::completion_for_mention,
Self::completion_for_mention, )
) .await;
.await; Ok(vec![completion_response])
Ok(vec![completion_response]) });
});
}
} }
if let Some((start_anchor, query, candidates)) = if let Some((start_anchor, query, candidates)) =
self.collect_emoji_candidates(buffer, end_anchor, cx) self.collect_emoji_candidates(buffer, end_anchor, cx)
&& !candidates.is_empty()
{ {
if !candidates.is_empty() { return cx.spawn(async move |_, cx| {
return cx.spawn(async move |_, cx| { let completion_response = Self::completions_for_candidates(
let completion_response = Self::completions_for_candidates( cx,
cx, query.as_str(),
query.as_str(), candidates,
candidates, start_anchor..end_anchor,
start_anchor..end_anchor, Self::completion_for_emoji,
Self::completion_for_emoji, )
) .await;
.await; Ok(vec![completion_response])
Ok(vec![completion_response]) });
});
}
} }
Task::ready(Ok(vec![CompletionResponse { Task::ready(Ok(vec![CompletionResponse {
@ -474,18 +472,17 @@ impl MessageEditor {
for range in ranges { for range in ranges {
text.clear(); text.clear();
text.extend(buffer.text_for_range(range.clone())); text.extend(buffer.text_for_range(range.clone()));
if let Some(username) = text.strip_prefix('@') { if let Some(username) = text.strip_prefix('@')
if let Some(user) = this && let Some(user) = this
.user_store .user_store
.read(cx) .read(cx)
.cached_user_by_github_login(username) .cached_user_by_github_login(username)
{ {
let start = multi_buffer.anchor_after(range.start); let start = multi_buffer.anchor_after(range.start);
let end = multi_buffer.anchor_after(range.end); let end = multi_buffer.anchor_after(range.end);
mentioned_user_ids.push(user.id); mentioned_user_ids.push(user.id);
anchor_ranges.push(start..end); anchor_ranges.push(start..end);
}
} }
} }

View file

@ -311,10 +311,10 @@ impl CollabPanel {
window, window,
|this: &mut Self, _, event, window, cx| { |this: &mut Self, _, event, window, cx| {
if let editor::EditorEvent::Blurred = event { if let editor::EditorEvent::Blurred = event {
if let Some(state) = &this.channel_editing_state { if let Some(state) = &this.channel_editing_state
if state.pending_name().is_some() { && state.pending_name().is_some()
return; {
} return;
} }
this.take_editing_state(window, cx); this.take_editing_state(window, cx);
this.update_entries(false, cx); this.update_entries(false, cx);
@ -491,11 +491,11 @@ impl CollabPanel {
if !self.collapsed_sections.contains(&Section::ActiveCall) { if !self.collapsed_sections.contains(&Section::ActiveCall) {
let room = room.read(cx); let room = room.read(cx);
if query.is_empty() { if query.is_empty()
if let Some(channel_id) = room.channel_id() { && let Some(channel_id) = room.channel_id()
self.entries.push(ListEntry::ChannelNotes { channel_id }); {
self.entries.push(ListEntry::ChannelChat { channel_id }); self.entries.push(ListEntry::ChannelNotes { channel_id });
} self.entries.push(ListEntry::ChannelChat { channel_id });
} }
// Populate the active user. // Populate the active user.
@ -639,10 +639,10 @@ impl CollabPanel {
&Default::default(), &Default::default(),
executor.clone(), executor.clone(),
)); ));
if let Some(state) = &self.channel_editing_state { if let Some(state) = &self.channel_editing_state
if matches!(state, ChannelEditingState::Create { location: None, .. }) { && matches!(state, ChannelEditingState::Create { location: None, .. })
self.entries.push(ListEntry::ChannelEditor { depth: 0 }); {
} self.entries.push(ListEntry::ChannelEditor { depth: 0 });
} }
let mut collapse_depth = None; let mut collapse_depth = None;
for mat in matches { for mat in matches {
@ -1552,98 +1552,93 @@ impl CollabPanel {
return; return;
} }
if let Some(selection) = self.selection { if let Some(selection) = self.selection
if let Some(entry) = self.entries.get(selection) { && let Some(entry) = self.entries.get(selection)
match entry { {
ListEntry::Header(section) => match section { match entry {
Section::ActiveCall => Self::leave_call(window, cx), ListEntry::Header(section) => match section {
Section::Channels => self.new_root_channel(window, cx), Section::ActiveCall => Self::leave_call(window, cx),
Section::Contacts => self.toggle_contact_finder(window, cx), Section::Channels => self.new_root_channel(window, cx),
Section::ContactRequests Section::Contacts => self.toggle_contact_finder(window, cx),
| Section::Online Section::ContactRequests
| Section::Offline | Section::Online
| Section::ChannelInvites => { | Section::Offline
self.toggle_section_expanded(*section, cx); | Section::ChannelInvites => {
} self.toggle_section_expanded(*section, cx);
},
ListEntry::Contact { contact, calling } => {
if contact.online && !contact.busy && !calling {
self.call(contact.user.id, window, cx);
}
} }
ListEntry::ParticipantProject { },
project_id, ListEntry::Contact { contact, calling } => {
host_user_id, if contact.online && !contact.busy && !calling {
.. self.call(contact.user.id, window, cx);
} => { }
if let Some(workspace) = self.workspace.upgrade() { }
let app_state = workspace.read(cx).app_state().clone(); ListEntry::ParticipantProject {
workspace::join_in_room_project( project_id,
*project_id, host_user_id,
*host_user_id, ..
app_state, } => {
cx, if let Some(workspace) = self.workspace.upgrade() {
) let app_state = workspace.read(cx).app_state().clone();
workspace::join_in_room_project(*project_id, *host_user_id, app_state, cx)
.detach_and_prompt_err( .detach_and_prompt_err(
"Failed to join project", "Failed to join project",
window, window,
cx, cx,
|_, _, _| None, |_, _, _| None,
); );
}
} }
ListEntry::ParticipantScreen { peer_id, .. } => {
let Some(peer_id) = peer_id else {
return;
};
if let Some(workspace) = self.workspace.upgrade() {
workspace.update(cx, |workspace, cx| {
workspace.open_shared_screen(*peer_id, window, cx)
});
}
}
ListEntry::Channel { channel, .. } => {
let is_active = maybe!({
let call_channel = ActiveCall::global(cx)
.read(cx)
.room()?
.read(cx)
.channel_id()?;
Some(call_channel == channel.id)
})
.unwrap_or(false);
if is_active {
self.open_channel_notes(channel.id, window, cx)
} else {
self.join_channel(channel.id, window, cx)
}
}
ListEntry::ContactPlaceholder => self.toggle_contact_finder(window, cx),
ListEntry::CallParticipant { user, peer_id, .. } => {
if Some(user) == self.user_store.read(cx).current_user().as_ref() {
Self::leave_call(window, cx);
} else if let Some(peer_id) = peer_id {
self.workspace
.update(cx, |workspace, cx| workspace.follow(*peer_id, window, cx))
.ok();
}
}
ListEntry::IncomingRequest(user) => {
self.respond_to_contact_request(user.id, true, window, cx)
}
ListEntry::ChannelInvite(channel) => {
self.respond_to_channel_invite(channel.id, true, cx)
}
ListEntry::ChannelNotes { channel_id } => {
self.open_channel_notes(*channel_id, window, cx)
}
ListEntry::ChannelChat { channel_id } => {
self.join_channel_chat(*channel_id, window, cx)
}
ListEntry::OutgoingRequest(_) => {}
ListEntry::ChannelEditor { .. } => {}
} }
ListEntry::ParticipantScreen { peer_id, .. } => {
let Some(peer_id) = peer_id else {
return;
};
if let Some(workspace) = self.workspace.upgrade() {
workspace.update(cx, |workspace, cx| {
workspace.open_shared_screen(*peer_id, window, cx)
});
}
}
ListEntry::Channel { channel, .. } => {
let is_active = maybe!({
let call_channel = ActiveCall::global(cx)
.read(cx)
.room()?
.read(cx)
.channel_id()?;
Some(call_channel == channel.id)
})
.unwrap_or(false);
if is_active {
self.open_channel_notes(channel.id, window, cx)
} else {
self.join_channel(channel.id, window, cx)
}
}
ListEntry::ContactPlaceholder => self.toggle_contact_finder(window, cx),
ListEntry::CallParticipant { user, peer_id, .. } => {
if Some(user) == self.user_store.read(cx).current_user().as_ref() {
Self::leave_call(window, cx);
} else if let Some(peer_id) = peer_id {
self.workspace
.update(cx, |workspace, cx| workspace.follow(*peer_id, window, cx))
.ok();
}
}
ListEntry::IncomingRequest(user) => {
self.respond_to_contact_request(user.id, true, window, cx)
}
ListEntry::ChannelInvite(channel) => {
self.respond_to_channel_invite(channel.id, true, cx)
}
ListEntry::ChannelNotes { channel_id } => {
self.open_channel_notes(*channel_id, window, cx)
}
ListEntry::ChannelChat { channel_id } => {
self.join_channel_chat(*channel_id, window, cx)
}
ListEntry::OutgoingRequest(_) => {}
ListEntry::ChannelEditor { .. } => {}
} }
} }
} }

View file

@ -121,13 +121,12 @@ impl NotificationPanel {
let notification_list = ListState::new(0, ListAlignment::Top, px(1000.)); let notification_list = ListState::new(0, ListAlignment::Top, px(1000.));
notification_list.set_scroll_handler(cx.listener( notification_list.set_scroll_handler(cx.listener(
|this, event: &ListScrollEvent, _, cx| { |this, event: &ListScrollEvent, _, cx| {
if event.count.saturating_sub(event.visible_range.end) < LOADING_THRESHOLD { if event.count.saturating_sub(event.visible_range.end) < LOADING_THRESHOLD
if let Some(task) = this && let Some(task) = this
.notification_store .notification_store
.update(cx, |store, cx| store.load_more_notifications(false, cx)) .update(cx, |store, cx| store.load_more_notifications(false, cx))
{ {
task.detach(); task.detach();
}
} }
}, },
)); ));
@ -469,20 +468,19 @@ impl NotificationPanel {
channel_id, channel_id,
.. ..
} = notification.clone() } = notification.clone()
&& let Some(workspace) = self.workspace.upgrade()
{ {
if let Some(workspace) = self.workspace.upgrade() { window.defer(cx, move |window, cx| {
window.defer(cx, move |window, cx| { workspace.update(cx, |workspace, cx| {
workspace.update(cx, |workspace, cx| { if let Some(panel) = workspace.focus_panel::<ChatPanel>(window, cx) {
if let Some(panel) = workspace.focus_panel::<ChatPanel>(window, cx) { panel.update(cx, |panel, cx| {
panel.update(cx, |panel, cx| { panel
panel .select_channel(ChannelId(channel_id), Some(message_id), cx)
.select_channel(ChannelId(channel_id), Some(message_id), cx) .detach_and_log_err(cx);
.detach_and_log_err(cx); });
}); }
}
});
}); });
} });
} }
} }
@ -491,18 +489,18 @@ impl NotificationPanel {
return false; return false;
} }
if let Notification::ChannelMessageMention { channel_id, .. } = &notification { if let Notification::ChannelMessageMention { channel_id, .. } = &notification
if let Some(workspace) = self.workspace.upgrade() { && let Some(workspace) = self.workspace.upgrade()
return if let Some(panel) = workspace.read(cx).panel::<ChatPanel>(cx) { {
let panel = panel.read(cx); return if let Some(panel) = workspace.read(cx).panel::<ChatPanel>(cx) {
panel.is_scrolled_to_bottom() let panel = panel.read(cx);
&& panel panel.is_scrolled_to_bottom()
.active_chat() && panel
.map_or(false, |chat| chat.read(cx).channel_id.0 == *channel_id) .active_chat()
} else { .map_or(false, |chat| chat.read(cx).channel_id.0 == *channel_id)
false } else {
}; false
} };
} }
false false
@ -582,16 +580,16 @@ impl NotificationPanel {
} }
fn remove_toast(&mut self, notification_id: u64, cx: &mut Context<Self>) { fn remove_toast(&mut self, notification_id: u64, cx: &mut Context<Self>) {
if let Some((current_id, _)) = &self.current_notification_toast { if let Some((current_id, _)) = &self.current_notification_toast
if *current_id == notification_id { && *current_id == notification_id
self.current_notification_toast.take(); {
self.workspace self.current_notification_toast.take();
.update(cx, |workspace, cx| { self.workspace
let id = NotificationId::unique::<NotificationToast>(); .update(cx, |workspace, cx| {
workspace.dismiss_notification(&id, cx) let id = NotificationId::unique::<NotificationToast>();
}) workspace.dismiss_notification(&id, cx)
.ok(); })
} .ok();
} }
} }

View file

@ -271,10 +271,10 @@ impl Client {
); );
} }
} else if let Ok(response) = serde_json::from_str::<AnyResponse>(&message) { } else if let Ok(response) = serde_json::from_str::<AnyResponse>(&message) {
if let Some(handlers) = response_handlers.lock().as_mut() { if let Some(handlers) = response_handlers.lock().as_mut()
if let Some(handler) = handlers.remove(&response.id) { && let Some(handler) = handlers.remove(&response.id)
handler(Ok(message.to_string())); {
} handler(Ok(message.to_string()));
} }
} else if let Ok(notification) = serde_json::from_str::<AnyNotification>(&message) { } else if let Ok(notification) = serde_json::from_str::<AnyNotification>(&message) {
let mut notification_handlers = notification_handlers.lock(); let mut notification_handlers = notification_handlers.lock();

View file

@ -608,15 +608,13 @@ impl Copilot {
sign_in_status: status, sign_in_status: status,
.. ..
}) = &mut this.server }) = &mut this.server
{ && let SignInStatus::SigningIn {
if let SignInStatus::SigningIn {
prompt: prompt_flow, prompt: prompt_flow,
.. ..
} = status } = status
{ {
*prompt_flow = Some(flow.clone()); *prompt_flow = Some(flow.clone());
cx.notify(); cx.notify();
}
} }
})?; })?;
let response = lsp let response = lsp
@ -782,59 +780,58 @@ impl Copilot {
event: &language::BufferEvent, event: &language::BufferEvent,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Result<()> { ) -> Result<()> {
if let Ok(server) = self.server.as_running() { if let Ok(server) = self.server.as_running()
if let Some(registered_buffer) = server.registered_buffers.get_mut(&buffer.entity_id()) && let Some(registered_buffer) = server.registered_buffers.get_mut(&buffer.entity_id())
{ {
match event { match event {
language::BufferEvent::Edited => { language::BufferEvent::Edited => {
drop(registered_buffer.report_changes(&buffer, cx)); drop(registered_buffer.report_changes(&buffer, cx));
} }
language::BufferEvent::Saved => { language::BufferEvent::Saved => {
server
.lsp
.notify::<lsp::notification::DidSaveTextDocument>(
&lsp::DidSaveTextDocumentParams {
text_document: lsp::TextDocumentIdentifier::new(
registered_buffer.uri.clone(),
),
text: None,
},
)?;
}
language::BufferEvent::FileHandleChanged
| language::BufferEvent::LanguageChanged => {
let new_language_id = id_for_language(buffer.read(cx).language());
let Ok(new_uri) = uri_for_buffer(&buffer, cx) else {
return Ok(());
};
if new_uri != registered_buffer.uri
|| new_language_id != registered_buffer.language_id
{
let old_uri = mem::replace(&mut registered_buffer.uri, new_uri);
registered_buffer.language_id = new_language_id;
server server
.lsp .lsp
.notify::<lsp::notification::DidSaveTextDocument>( .notify::<lsp::notification::DidCloseTextDocument>(
&lsp::DidSaveTextDocumentParams { &lsp::DidCloseTextDocumentParams {
text_document: lsp::TextDocumentIdentifier::new( text_document: lsp::TextDocumentIdentifier::new(old_uri),
},
)?;
server
.lsp
.notify::<lsp::notification::DidOpenTextDocument>(
&lsp::DidOpenTextDocumentParams {
text_document: lsp::TextDocumentItem::new(
registered_buffer.uri.clone(), registered_buffer.uri.clone(),
registered_buffer.language_id.clone(),
registered_buffer.snapshot_version,
registered_buffer.snapshot.text(),
), ),
text: None,
}, },
)?; )?;
} }
language::BufferEvent::FileHandleChanged
| language::BufferEvent::LanguageChanged => {
let new_language_id = id_for_language(buffer.read(cx).language());
let Ok(new_uri) = uri_for_buffer(&buffer, cx) else {
return Ok(());
};
if new_uri != registered_buffer.uri
|| new_language_id != registered_buffer.language_id
{
let old_uri = mem::replace(&mut registered_buffer.uri, new_uri);
registered_buffer.language_id = new_language_id;
server
.lsp
.notify::<lsp::notification::DidCloseTextDocument>(
&lsp::DidCloseTextDocumentParams {
text_document: lsp::TextDocumentIdentifier::new(old_uri),
},
)?;
server
.lsp
.notify::<lsp::notification::DidOpenTextDocument>(
&lsp::DidOpenTextDocumentParams {
text_document: lsp::TextDocumentItem::new(
registered_buffer.uri.clone(),
registered_buffer.language_id.clone(),
registered_buffer.snapshot_version,
registered_buffer.snapshot.text(),
),
},
)?;
}
}
_ => {}
} }
_ => {}
} }
} }
@ -842,17 +839,17 @@ impl Copilot {
} }
fn unregister_buffer(&mut self, buffer: &WeakEntity<Buffer>) { fn unregister_buffer(&mut self, buffer: &WeakEntity<Buffer>) {
if let Ok(server) = self.server.as_running() { if let Ok(server) = self.server.as_running()
if let Some(buffer) = server.registered_buffers.remove(&buffer.entity_id()) { && let Some(buffer) = server.registered_buffers.remove(&buffer.entity_id())
server {
.lsp server
.notify::<lsp::notification::DidCloseTextDocument>( .lsp
&lsp::DidCloseTextDocumentParams { .notify::<lsp::notification::DidCloseTextDocument>(
text_document: lsp::TextDocumentIdentifier::new(buffer.uri), &lsp::DidCloseTextDocumentParams {
}, text_document: lsp::TextDocumentIdentifier::new(buffer.uri),
) },
.ok(); )
} .ok();
} }
} }

View file

@ -99,10 +99,10 @@ impl JsDebugAdapter {
} }
} }
if let Some(env) = configuration.get("env").cloned() { if let Some(env) = configuration.get("env").cloned()
if let Ok(env) = serde_json::from_value(env) { && let Ok(env) = serde_json::from_value(env)
envs = env; {
} envs = env;
} }
configuration configuration

View file

@ -661,11 +661,11 @@ impl ToolbarItemView for DapLogToolbarItemView {
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> workspace::ToolbarItemLocation { ) -> workspace::ToolbarItemLocation {
if let Some(item) = active_pane_item { if let Some(item) = active_pane_item
if let Some(log_view) = item.downcast::<DapLogView>() { && let Some(log_view) = item.downcast::<DapLogView>()
self.log_view = Some(log_view.clone()); {
return workspace::ToolbarItemLocation::PrimaryLeft; self.log_view = Some(log_view.clone());
} return workspace::ToolbarItemLocation::PrimaryLeft;
} }
self.log_view = None; self.log_view = None;

View file

@ -530,10 +530,9 @@ impl DebugPanel {
.active_session .active_session
.as_ref() .as_ref()
.map(|session| session.entity_id()) .map(|session| session.entity_id())
&& active_session_id == entity_id
{ {
if active_session_id == entity_id { this.active_session = this.sessions_with_children.keys().next().cloned();
this.active_session = this.sessions_with_children.keys().next().cloned();
}
} }
cx.notify() cx.notify()
}) })
@ -1302,10 +1301,10 @@ impl DebugPanel {
cx: &mut Context<'_, Self>, cx: &mut Context<'_, Self>,
) -> Option<SharedString> { ) -> Option<SharedString> {
let adapter = parent_session.read(cx).adapter(); let adapter = parent_session.read(cx).adapter();
if let Some(adapter) = DapRegistry::global(cx).adapter(&adapter) { if let Some(adapter) = DapRegistry::global(cx).adapter(&adapter)
if let Some(label) = adapter.label_for_child_session(request) { && let Some(label) = adapter.label_for_child_session(request)
return Some(label.into()); {
} return Some(label.into());
} }
None None
} }

View file

@ -343,10 +343,10 @@ impl NewProcessModal {
return; return;
} }
if let NewProcessMode::Launch = &self.mode { if let NewProcessMode::Launch = &self.mode
if self.configure_mode.read(cx).save_to_debug_json.selected() { && self.configure_mode.read(cx).save_to_debug_json.selected()
self.save_debug_scenario(window, cx); {
} self.save_debug_scenario(window, cx);
} }
let Some(debugger) = self.debugger.clone() else { let Some(debugger) = self.debugger.clone() else {

View file

@ -239,11 +239,9 @@ impl BreakpointList {
} }
fn select_next(&mut self, _: &menu::SelectNext, window: &mut Window, cx: &mut Context<Self>) { fn select_next(&mut self, _: &menu::SelectNext, window: &mut Window, cx: &mut Context<Self>) {
if self.strip_mode.is_some() { if self.strip_mode.is_some() && self.input.focus_handle(cx).contains_focused(window, cx) {
if self.input.focus_handle(cx).contains_focused(window, cx) { cx.propagate();
cx.propagate(); return;
return;
}
} }
let ix = match self.selected_ix { let ix = match self.selected_ix {
_ if self.breakpoints.len() == 0 => None, _ if self.breakpoints.len() == 0 => None,
@ -265,11 +263,9 @@ impl BreakpointList {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if self.strip_mode.is_some() { if self.strip_mode.is_some() && self.input.focus_handle(cx).contains_focused(window, cx) {
if self.input.focus_handle(cx).contains_focused(window, cx) { cx.propagate();
cx.propagate(); return;
return;
}
} }
let ix = match self.selected_ix { let ix = match self.selected_ix {
_ if self.breakpoints.len() == 0 => None, _ if self.breakpoints.len() == 0 => None,
@ -286,11 +282,9 @@ impl BreakpointList {
} }
fn select_first(&mut self, _: &menu::SelectFirst, window: &mut Window, cx: &mut Context<Self>) { fn select_first(&mut self, _: &menu::SelectFirst, window: &mut Window, cx: &mut Context<Self>) {
if self.strip_mode.is_some() { if self.strip_mode.is_some() && self.input.focus_handle(cx).contains_focused(window, cx) {
if self.input.focus_handle(cx).contains_focused(window, cx) { cx.propagate();
cx.propagate(); return;
return;
}
} }
let ix = if self.breakpoints.len() > 0 { let ix = if self.breakpoints.len() > 0 {
Some(0) Some(0)
@ -301,11 +295,9 @@ impl BreakpointList {
} }
fn select_last(&mut self, _: &menu::SelectLast, window: &mut Window, cx: &mut Context<Self>) { fn select_last(&mut self, _: &menu::SelectLast, window: &mut Window, cx: &mut Context<Self>) {
if self.strip_mode.is_some() { if self.strip_mode.is_some() && self.input.focus_handle(cx).contains_focused(window, cx) {
if self.input.focus_handle(cx).contains_focused(window, cx) { cx.propagate();
cx.propagate(); return;
return;
}
} }
let ix = if self.breakpoints.len() > 0 { let ix = if self.breakpoints.len() > 0 {
Some(self.breakpoints.len() - 1) Some(self.breakpoints.len() - 1)
@ -401,11 +393,9 @@ impl BreakpointList {
let Some(entry) = self.selected_ix.and_then(|ix| self.breakpoints.get_mut(ix)) else { let Some(entry) = self.selected_ix.and_then(|ix| self.breakpoints.get_mut(ix)) else {
return; return;
}; };
if self.strip_mode.is_some() { if self.strip_mode.is_some() && self.input.focus_handle(cx).contains_focused(window, cx) {
if self.input.focus_handle(cx).contains_focused(window, cx) { cx.propagate();
cx.propagate(); return;
return;
}
} }
match &mut entry.kind { match &mut entry.kind {

View file

@ -611,17 +611,16 @@ impl ConsoleQueryBarCompletionProvider {
for variable in console.variable_list.update(cx, |variable_list, cx| { for variable in console.variable_list.update(cx, |variable_list, cx| {
variable_list.completion_variables(cx) variable_list.completion_variables(cx)
}) { }) {
if let Some(evaluate_name) = &variable.evaluate_name { if let Some(evaluate_name) = &variable.evaluate_name
if variables && variables
.insert(evaluate_name.clone(), variable.value.clone()) .insert(evaluate_name.clone(), variable.value.clone())
.is_none() .is_none()
{ {
string_matches.push(StringMatchCandidate { string_matches.push(StringMatchCandidate {
id: 0, id: 0,
string: evaluate_name.clone(), string: evaluate_name.clone(),
char_bag: evaluate_name.chars().collect(), char_bag: evaluate_name.chars().collect(),
}); });
}
} }
if variables if variables

View file

@ -639,17 +639,15 @@ impl ProjectDiagnosticsEditor {
#[cfg(test)] #[cfg(test)]
let cloned_blocks = blocks.clone(); let cloned_blocks = blocks.clone();
if was_empty { if was_empty && let Some(anchor_range) = anchor_ranges.first() {
if let Some(anchor_range) = anchor_ranges.first() { let range_to_select = anchor_range.start..anchor_range.start;
let range_to_select = anchor_range.start..anchor_range.start; this.editor.update(cx, |editor, cx| {
this.editor.update(cx, |editor, cx| { editor.change_selections(Default::default(), window, cx, |s| {
editor.change_selections(Default::default(), window, cx, |s| { s.select_anchor_ranges([range_to_select]);
s.select_anchor_ranges([range_to_select]); })
}) });
}); if this.focus_handle.is_focused(window) {
if this.focus_handle.is_focused(window) { this.editor.read(cx).focus_handle(cx).focus(window);
this.editor.read(cx).focus_handle(cx).focus(window);
}
} }
} }
@ -980,18 +978,16 @@ async fn heuristic_syntactic_expand(
// Remove blank lines from start and end // Remove blank lines from start and end
if let Some(start_row) = (outline_range.start.row..outline_range.end.row) if let Some(start_row) = (outline_range.start.row..outline_range.end.row)
.find(|row| !snapshot.line_indent_for_row(*row).is_line_blank()) .find(|row| !snapshot.line_indent_for_row(*row).is_line_blank())
{ && let Some(end_row) = (outline_range.start.row..outline_range.end.row + 1)
if let Some(end_row) = (outline_range.start.row..outline_range.end.row + 1)
.rev() .rev()
.find(|row| !snapshot.line_indent_for_row(*row).is_line_blank()) .find(|row| !snapshot.line_indent_for_row(*row).is_line_blank())
{ {
let row_count = end_row.saturating_sub(start_row); let row_count = end_row.saturating_sub(start_row);
if row_count <= max_row_count { if row_count <= max_row_count {
return Some(RangeInclusive::new( return Some(RangeInclusive::new(
outline_range.start.row, outline_range.start.row,
outline_range.end.row, outline_range.end.row,
)); ));
}
} }
} }
} }

View file

@ -969,13 +969,13 @@ impl DisplaySnapshot {
if let Some(chunk_highlight) = chunk.highlight_style { if let Some(chunk_highlight) = chunk.highlight_style {
// For color inlays, blend the color with the editor background // For color inlays, blend the color with the editor background
let mut processed_highlight = chunk_highlight; let mut processed_highlight = chunk_highlight;
if chunk.is_inlay { if chunk.is_inlay
if let Some(inlay_color) = chunk_highlight.color { && let Some(inlay_color) = chunk_highlight.color
// Only blend if the color has transparency (alpha < 1.0) {
if inlay_color.a < 1.0 { // Only blend if the color has transparency (alpha < 1.0)
let blended_color = editor_style.background.blend(inlay_color); if inlay_color.a < 1.0 {
processed_highlight.color = Some(blended_color); let blended_color = editor_style.background.blend(inlay_color);
} processed_highlight.color = Some(blended_color);
} }
} }
@ -2351,11 +2351,12 @@ pub mod tests {
.highlight_style .highlight_style
.and_then(|style| style.color) .and_then(|style| style.color)
.map_or(black, |color| color.to_rgb()); .map_or(black, |color| color.to_rgb());
if let Some((last_chunk, last_severity, last_color)) = chunks.last_mut() { if let Some((last_chunk, last_severity, last_color)) = chunks.last_mut()
if *last_severity == chunk.diagnostic_severity && *last_color == color { && *last_severity == chunk.diagnostic_severity
last_chunk.push_str(chunk.text); && *last_color == color
continue; {
} last_chunk.push_str(chunk.text);
continue;
} }
chunks.push((chunk.text.to_string(), chunk.diagnostic_severity, color)); chunks.push((chunk.text.to_string(), chunk.diagnostic_severity, color));
@ -2901,11 +2902,12 @@ pub mod tests {
.syntax_highlight_id .syntax_highlight_id
.and_then(|id| id.style(theme)?.color); .and_then(|id| id.style(theme)?.color);
let highlight_color = chunk.highlight_style.and_then(|style| style.color); let highlight_color = chunk.highlight_style.and_then(|style| style.color);
if let Some((last_chunk, last_syntax_color, last_highlight_color)) = chunks.last_mut() { if let Some((last_chunk, last_syntax_color, last_highlight_color)) = chunks.last_mut()
if syntax_color == *last_syntax_color && highlight_color == *last_highlight_color { && syntax_color == *last_syntax_color
last_chunk.push_str(chunk.text); && highlight_color == *last_highlight_color
continue; {
} last_chunk.push_str(chunk.text);
continue;
} }
chunks.push((chunk.text.to_string(), syntax_color, highlight_color)); chunks.push((chunk.text.to_string(), syntax_color, highlight_color));
} }

View file

@ -525,26 +525,25 @@ impl BlockMap {
// * Below blocks that end at the start of the edit // * Below blocks that end at the start of the edit
// However, if we hit a replace block that ends at the start of the edit we want to reconstruct it. // However, if we hit a replace block that ends at the start of the edit we want to reconstruct it.
new_transforms.append(cursor.slice(&old_start, Bias::Left), &()); new_transforms.append(cursor.slice(&old_start, Bias::Left), &());
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item()
if transform.summary.input_rows > 0 && transform.summary.input_rows > 0
&& cursor.end() == old_start && cursor.end() == old_start
&& transform && transform
.block .block
.as_ref() .as_ref()
.map_or(true, |b| !b.is_replacement()) .map_or(true, |b| !b.is_replacement())
{ {
// Preserve the transform (push and next) // Preserve the transform (push and next)
new_transforms.push(transform.clone(), &()); new_transforms.push(transform.clone(), &());
cursor.next(); cursor.next();
// Preserve below blocks at end of edit // Preserve below blocks at end of edit
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if transform.block.as_ref().map_or(false, |b| b.place_below()) { if transform.block.as_ref().map_or(false, |b| b.place_below()) {
new_transforms.push(transform.clone(), &()); new_transforms.push(transform.clone(), &());
cursor.next(); cursor.next();
} else { } else {
break; break;
}
} }
} }
} }
@ -657,10 +656,10 @@ impl BlockMap {
.iter() .iter()
.filter_map(|block| { .filter_map(|block| {
let placement = block.placement.to_wrap_row(wrap_snapshot)?; let placement = block.placement.to_wrap_row(wrap_snapshot)?;
if let BlockPlacement::Above(row) = placement { if let BlockPlacement::Above(row) = placement
if row < new_start { && row < new_start
return None; {
} return None;
} }
Some((placement, Block::Custom(block.clone()))) Some((placement, Block::Custom(block.clone())))
}), }),
@ -977,10 +976,10 @@ impl BlockMapReader<'_> {
break; break;
} }
if let Some(BlockId::Custom(id)) = transform.block.as_ref().map(|block| block.id()) { if let Some(BlockId::Custom(id)) = transform.block.as_ref().map(|block| block.id())
if id == block_id { && id == block_id
return Some(cursor.start().1); {
} return Some(cursor.start().1);
} }
cursor.next(); cursor.next();
} }
@ -1299,14 +1298,14 @@ impl BlockSnapshot {
let mut input_start = transform_input_start; let mut input_start = transform_input_start;
let mut input_end = transform_input_start; let mut input_end = transform_input_start;
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item()
if transform.block.is_none() { && transform.block.is_none()
input_start += rows.start - transform_output_start; {
input_end += cmp::min( input_start += rows.start - transform_output_start;
rows.end - transform_output_start, input_end += cmp::min(
transform.summary.input_rows, rows.end - transform_output_start,
); transform.summary.input_rows,
} );
} }
BlockChunks { BlockChunks {
@ -1472,18 +1471,18 @@ impl BlockSnapshot {
longest_row_chars = summary.longest_row_chars; longest_row_chars = summary.longest_row_chars;
} }
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item()
if transform.block.is_none() { && transform.block.is_none()
let Dimensions(output_start, input_start, _) = cursor.start(); {
let overshoot = range.end.0 - output_start.0; let Dimensions(output_start, input_start, _) = cursor.start();
let wrap_start_row = input_start.0; let overshoot = range.end.0 - output_start.0;
let wrap_end_row = input_start.0 + overshoot; let wrap_start_row = input_start.0;
let summary = self let wrap_end_row = input_start.0 + overshoot;
.wrap_snapshot let summary = self
.text_summary_for_range(wrap_start_row..wrap_end_row); .wrap_snapshot
if summary.longest_row_chars > longest_row_chars { .text_summary_for_range(wrap_start_row..wrap_end_row);
longest_row = BlockRow(output_start.0 + summary.longest_row); if summary.longest_row_chars > longest_row_chars {
} longest_row = BlockRow(output_start.0 + summary.longest_row);
} }
} }
} }
@ -1557,12 +1556,11 @@ impl BlockSnapshot {
match transform.block.as_ref() { match transform.block.as_ref() {
Some(block) => { Some(block) => {
if block.is_replacement() { if block.is_replacement()
if ((bias == Bias::Left || search_left) && output_start <= point.0) && (((bias == Bias::Left || search_left) && output_start <= point.0)
|| (!search_left && output_start >= point.0) || (!search_left && output_start >= point.0))
{ {
return BlockPoint(output_start); return BlockPoint(output_start);
}
} }
} }
None => { None => {
@ -3228,34 +3226,32 @@ mod tests {
let mut is_in_replace_block = false; let mut is_in_replace_block = false;
if let Some((BlockPlacement::Replace(replace_range), block)) = if let Some((BlockPlacement::Replace(replace_range), block)) =
sorted_blocks_iter.peek() sorted_blocks_iter.peek()
&& wrap_row >= replace_range.start().0
{ {
if wrap_row >= replace_range.start().0 { is_in_replace_block = true;
is_in_replace_block = true;
if wrap_row == replace_range.start().0 { if wrap_row == replace_range.start().0 {
if matches!(block, Block::FoldedBuffer { .. }) { if matches!(block, Block::FoldedBuffer { .. }) {
expected_buffer_rows.push(None); expected_buffer_rows.push(None);
} else { } else {
expected_buffer_rows expected_buffer_rows.push(input_buffer_rows[multibuffer_row as usize]);
.push(input_buffer_rows[multibuffer_row as usize]);
}
} }
}
if wrap_row == replace_range.end().0 { if wrap_row == replace_range.end().0 {
expected_block_positions.push((block_row, block.id())); expected_block_positions.push((block_row, block.id()));
let text = "\n".repeat((block.height() - 1) as usize); let text = "\n".repeat((block.height() - 1) as usize);
if block_row > 0 { if block_row > 0 {
expected_text.push('\n'); expected_text.push('\n');
}
expected_text.push_str(&text);
for _ in 1..block.height() {
expected_buffer_rows.push(None);
}
block_row += block.height();
sorted_blocks_iter.next();
} }
expected_text.push_str(&text);
for _ in 1..block.height() {
expected_buffer_rows.push(None);
}
block_row += block.height();
sorted_blocks_iter.next();
} }
} }

View file

@ -289,25 +289,25 @@ impl FoldMapWriter<'_> {
let ChunkRendererId::Fold(id) = id else { let ChunkRendererId::Fold(id) = id else {
continue; continue;
}; };
if let Some(metadata) = self.0.snapshot.fold_metadata_by_id.get(&id).cloned() { if let Some(metadata) = self.0.snapshot.fold_metadata_by_id.get(&id).cloned()
if Some(new_width) != metadata.width { && Some(new_width) != metadata.width
let buffer_start = metadata.range.start.to_offset(buffer); {
let buffer_end = metadata.range.end.to_offset(buffer); let buffer_start = metadata.range.start.to_offset(buffer);
let inlay_range = inlay_snapshot.to_inlay_offset(buffer_start) let buffer_end = metadata.range.end.to_offset(buffer);
..inlay_snapshot.to_inlay_offset(buffer_end); let inlay_range = inlay_snapshot.to_inlay_offset(buffer_start)
edits.push(InlayEdit { ..inlay_snapshot.to_inlay_offset(buffer_end);
old: inlay_range.clone(), edits.push(InlayEdit {
new: inlay_range.clone(), old: inlay_range.clone(),
}); new: inlay_range.clone(),
});
self.0.snapshot.fold_metadata_by_id.insert( self.0.snapshot.fold_metadata_by_id.insert(
id, id,
FoldMetadata { FoldMetadata {
range: metadata.range, range: metadata.range,
width: Some(new_width), width: Some(new_width),
}, },
); );
}
} }
} }
@ -417,18 +417,18 @@ impl FoldMap {
cursor.seek(&InlayOffset(0), Bias::Right); cursor.seek(&InlayOffset(0), Bias::Right);
while let Some(mut edit) = inlay_edits_iter.next() { while let Some(mut edit) = inlay_edits_iter.next() {
if let Some(item) = cursor.item() { if let Some(item) = cursor.item()
if !item.is_fold() { && !item.is_fold()
new_transforms.update_last( {
|transform| { new_transforms.update_last(
if !transform.is_fold() { |transform| {
transform.summary.add_summary(&item.summary, &()); if !transform.is_fold() {
cursor.next(); transform.summary.add_summary(&item.summary, &());
} cursor.next();
}, }
&(), },
); &(),
} );
} }
new_transforms.append(cursor.slice(&edit.old.start, Bias::Left), &()); new_transforms.append(cursor.slice(&edit.old.start, Bias::Left), &());
edit.new.start -= edit.old.start - *cursor.start(); edit.new.start -= edit.old.start - *cursor.start();

View file

@ -557,11 +557,11 @@ impl InlayMap {
let mut buffer_edits_iter = buffer_edits.iter().peekable(); let mut buffer_edits_iter = buffer_edits.iter().peekable();
while let Some(buffer_edit) = buffer_edits_iter.next() { while let Some(buffer_edit) = buffer_edits_iter.next() {
new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left), &()); new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left), &());
if let Some(Transform::Isomorphic(transform)) = cursor.item() { if let Some(Transform::Isomorphic(transform)) = cursor.item()
if cursor.end().0 == buffer_edit.old.start { && cursor.end().0 == buffer_edit.old.start
push_isomorphic(&mut new_transforms, *transform); {
cursor.next(); push_isomorphic(&mut new_transforms, *transform);
} cursor.next();
} }
// Remove all the inlays and transforms contained by the edit. // Remove all the inlays and transforms contained by the edit.

View file

@ -249,48 +249,48 @@ impl WrapMap {
return; return;
} }
if let Some(wrap_width) = self.wrap_width { if let Some(wrap_width) = self.wrap_width
if self.background_task.is_none() { && self.background_task.is_none()
let pending_edits = self.pending_edits.clone(); {
let mut snapshot = self.snapshot.clone(); let pending_edits = self.pending_edits.clone();
let text_system = cx.text_system().clone(); let mut snapshot = self.snapshot.clone();
let (font, font_size) = self.font_with_size.clone(); let text_system = cx.text_system().clone();
let update_task = cx.background_spawn(async move { let (font, font_size) = self.font_with_size.clone();
let mut edits = Patch::default(); let update_task = cx.background_spawn(async move {
let mut line_wrapper = text_system.line_wrapper(font, font_size); let mut edits = Patch::default();
for (tab_snapshot, tab_edits) in pending_edits { let mut line_wrapper = text_system.line_wrapper(font, font_size);
let wrap_edits = snapshot for (tab_snapshot, tab_edits) in pending_edits {
.update(tab_snapshot, &tab_edits, wrap_width, &mut line_wrapper) let wrap_edits = snapshot
.await; .update(tab_snapshot, &tab_edits, wrap_width, &mut line_wrapper)
edits = edits.compose(&wrap_edits); .await;
} edits = edits.compose(&wrap_edits);
(snapshot, edits) }
}); (snapshot, edits)
});
match cx match cx
.background_executor() .background_executor()
.block_with_timeout(Duration::from_millis(1), update_task) .block_with_timeout(Duration::from_millis(1), update_task)
{ {
Ok((snapshot, output_edits)) => { Ok((snapshot, output_edits)) => {
self.snapshot = snapshot; self.snapshot = snapshot;
self.edits_since_sync = self.edits_since_sync.compose(&output_edits); self.edits_since_sync = self.edits_since_sync.compose(&output_edits);
} }
Err(update_task) => { Err(update_task) => {
self.background_task = Some(cx.spawn(async move |this, cx| { self.background_task = Some(cx.spawn(async move |this, cx| {
let (snapshot, edits) = update_task.await; let (snapshot, edits) = update_task.await;
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.snapshot = snapshot; this.snapshot = snapshot;
this.edits_since_sync = this this.edits_since_sync = this
.edits_since_sync .edits_since_sync
.compose(mem::take(&mut this.interpolated_edits).invert()) .compose(mem::take(&mut this.interpolated_edits).invert())
.compose(&edits); .compose(&edits);
this.background_task = None; this.background_task = None;
this.flush_edits(cx); this.flush_edits(cx);
cx.notify(); cx.notify();
}) })
.ok(); .ok();
})); }));
}
} }
} }
} }
@ -1065,12 +1065,12 @@ impl sum_tree::Item for Transform {
} }
fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) { fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) {
if let Some(last_transform) = transforms.last_mut() { if let Some(last_transform) = transforms.last_mut()
if last_transform.is_isomorphic() { && last_transform.is_isomorphic()
last_transform.summary.input += &summary; {
last_transform.summary.output += &summary; last_transform.summary.input += &summary;
return; last_transform.summary.output += &summary;
} return;
} }
transforms.push(Transform::isomorphic(summary)); transforms.push(Transform::isomorphic(summary));
} }

File diff suppressed because it is too large Load diff

View file

@ -917,6 +917,10 @@ impl EditorElement {
} else if cfg!(any(target_os = "linux", target_os = "freebsd")) } else if cfg!(any(target_os = "linux", target_os = "freebsd"))
&& event.button == MouseButton::Middle && event.button == MouseButton::Middle
{ {
#[allow(
clippy::collapsible_if,
reason = "The cfg-block below makes this a false positive"
)]
if !text_hitbox.is_hovered(window) || editor.read_only(cx) { if !text_hitbox.is_hovered(window) || editor.read_only(cx) {
return; return;
} }
@ -1387,29 +1391,27 @@ impl EditorElement {
ref drop_cursor, ref drop_cursor,
ref hide_drop_cursor, ref hide_drop_cursor,
} = editor.selection_drag_state } = editor.selection_drag_state
&& !hide_drop_cursor
&& (drop_cursor
.start
.cmp(&selection.start, &snapshot.buffer_snapshot)
.eq(&Ordering::Less)
|| drop_cursor
.end
.cmp(&selection.end, &snapshot.buffer_snapshot)
.eq(&Ordering::Greater))
{ {
if !hide_drop_cursor let drag_cursor_layout = SelectionLayout::new(
&& (drop_cursor drop_cursor.clone(),
.start false,
.cmp(&selection.start, &snapshot.buffer_snapshot) CursorShape::Bar,
.eq(&Ordering::Less) &snapshot.display_snapshot,
|| drop_cursor false,
.end false,
.cmp(&selection.end, &snapshot.buffer_snapshot) None,
.eq(&Ordering::Greater)) );
{ let absent_color = cx.theme().players().absent();
let drag_cursor_layout = SelectionLayout::new( selections.push((absent_color, vec![drag_cursor_layout]));
drop_cursor.clone(),
false,
CursorShape::Bar,
&snapshot.display_snapshot,
false,
false,
None,
);
let absent_color = cx.theme().players().absent();
selections.push((absent_color, vec![drag_cursor_layout]));
}
} }
} }
@ -1420,19 +1422,15 @@ impl EditorElement {
CollaboratorId::PeerId(peer_id) => { CollaboratorId::PeerId(peer_id) => {
if let Some(collaborator) = if let Some(collaborator) =
collaboration_hub.collaborators(cx).get(&peer_id) collaboration_hub.collaborators(cx).get(&peer_id)
{ && let Some(participant_index) = collaboration_hub
if let Some(participant_index) = collaboration_hub
.user_participant_indices(cx) .user_participant_indices(cx)
.get(&collaborator.user_id) .get(&collaborator.user_id)
{ && let Some((local_selection_style, _)) = selections.first_mut()
if let Some((local_selection_style, _)) = selections.first_mut() {
{ *local_selection_style = cx
*local_selection_style = cx .theme()
.theme() .players()
.players() .color_for_participant(participant_index.0);
.color_for_participant(participant_index.0);
}
}
} }
} }
CollaboratorId::Agent => { CollaboratorId::Agent => {
@ -3518,33 +3516,33 @@ impl EditorElement {
let mut x_offset = px(0.); let mut x_offset = px(0.);
let mut is_block = true; let mut is_block = true;
if let BlockId::Custom(custom_block_id) = block_id { if let BlockId::Custom(custom_block_id) = block_id
if block.has_height() { && block.has_height()
if block.place_near() { {
if let Some((x_target, line_width)) = x_position { if block.place_near()
let margin = em_width * 2; && let Some((x_target, line_width)) = x_position
if line_width + final_size.width + margin {
< editor_width + editor_margins.gutter.full_width() let margin = em_width * 2;
&& !row_block_types.contains_key(&(row - 1)) if line_width + final_size.width + margin
&& element_height_in_lines == 1 < editor_width + editor_margins.gutter.full_width()
{ && !row_block_types.contains_key(&(row - 1))
x_offset = line_width + margin; && element_height_in_lines == 1
row = row - 1; {
is_block = false; x_offset = line_width + margin;
element_height_in_lines = 0; row = row - 1;
row_block_types.insert(row, is_block); is_block = false;
} else { element_height_in_lines = 0;
let max_offset = editor_width + editor_margins.gutter.full_width() row_block_types.insert(row, is_block);
- final_size.width; } else {
let min_offset = (x_target + em_width - final_size.width) let max_offset =
.max(editor_margins.gutter.full_width()); editor_width + editor_margins.gutter.full_width() - final_size.width;
x_offset = x_target.min(max_offset).max(min_offset); let min_offset = (x_target + em_width - final_size.width)
} .max(editor_margins.gutter.full_width());
} x_offset = x_target.min(max_offset).max(min_offset);
};
if element_height_in_lines != block.height() {
resized_blocks.insert(custom_block_id, element_height_in_lines);
} }
};
if element_height_in_lines != block.height() {
resized_blocks.insert(custom_block_id, element_height_in_lines);
} }
} }
for i in 0..element_height_in_lines { for i in 0..element_height_in_lines {
@ -3987,60 +3985,58 @@ impl EditorElement {
} }
} }
if let Some(focused_block) = focused_block { if let Some(focused_block) = focused_block
if let Some(focus_handle) = focused_block.focus_handle.upgrade() { && let Some(focus_handle) = focused_block.focus_handle.upgrade()
if focus_handle.is_focused(window) { && focus_handle.is_focused(window)
if let Some(block) = snapshot.block_for_id(focused_block.id) { && let Some(block) = snapshot.block_for_id(focused_block.id)
let style = block.style(); {
let width = match style { let style = block.style();
BlockStyle::Fixed => AvailableSpace::MinContent, let width = match style {
BlockStyle::Flex => AvailableSpace::Definite( BlockStyle::Fixed => AvailableSpace::MinContent,
hitbox BlockStyle::Flex => AvailableSpace::Definite(
.size hitbox
.width .size
.max(fixed_block_max_width) .width
.max(editor_margins.gutter.width + *scroll_width), .max(fixed_block_max_width)
), .max(editor_margins.gutter.width + *scroll_width),
BlockStyle::Sticky => AvailableSpace::Definite(hitbox.size.width), ),
}; BlockStyle::Sticky => AvailableSpace::Definite(hitbox.size.width),
};
if let Some((element, element_size, _, x_offset)) = self.render_block( if let Some((element, element_size, _, x_offset)) = self.render_block(
&block, &block,
width, width,
focused_block.id, focused_block.id,
rows.end, rows.end,
snapshot, snapshot,
text_x, text_x,
&rows, &rows,
line_layouts, line_layouts,
editor_margins, editor_margins,
line_height, line_height,
em_width, em_width,
text_hitbox, text_hitbox,
editor_width, editor_width,
scroll_width, scroll_width,
&mut resized_blocks, &mut resized_blocks,
&mut row_block_types, &mut row_block_types,
selections, selections,
selected_buffer_ids, selected_buffer_ids,
is_row_soft_wrapped, is_row_soft_wrapped,
sticky_header_excerpt_id, sticky_header_excerpt_id,
window, window,
cx, cx,
) { ) {
blocks.push(BlockLayout { blocks.push(BlockLayout {
id: block.id(), id: block.id(),
x_offset, x_offset,
row: None, row: None,
element, element,
available_space: size(width, element_size.height.into()), available_space: size(width, element_size.height.into()),
style, style,
overlaps_gutter: true, overlaps_gutter: true,
is_buffer_header: block.is_buffer_header(), is_buffer_header: block.is_buffer_header(),
}); });
}
}
}
} }
} }
@ -4203,19 +4199,19 @@ impl EditorElement {
edit_prediction_popover_visible = true; edit_prediction_popover_visible = true;
} }
if editor.context_menu_visible() { if editor.context_menu_visible()
if let Some(crate::ContextMenuOrigin::Cursor) = editor.context_menu_origin() { && let Some(crate::ContextMenuOrigin::Cursor) = editor.context_menu_origin()
let (min_height_in_lines, max_height_in_lines) = editor {
.context_menu_options let (min_height_in_lines, max_height_in_lines) = editor
.as_ref() .context_menu_options
.map_or((3, 12), |options| { .as_ref()
(options.min_entries_visible, options.max_entries_visible) .map_or((3, 12), |options| {
}); (options.min_entries_visible, options.max_entries_visible)
});
min_menu_height += line_height * min_height_in_lines as f32 + POPOVER_Y_PADDING; min_menu_height += line_height * min_height_in_lines as f32 + POPOVER_Y_PADDING;
max_menu_height += line_height * max_height_in_lines as f32 + POPOVER_Y_PADDING; max_menu_height += line_height * max_height_in_lines as f32 + POPOVER_Y_PADDING;
context_menu_visible = true; context_menu_visible = true;
}
} }
context_menu_placement = editor context_menu_placement = editor
.context_menu_options .context_menu_options
@ -5761,16 +5757,15 @@ impl EditorElement {
cx: &mut App, cx: &mut App,
) { ) {
for (_, hunk_hitbox) in &layout.display_hunks { for (_, hunk_hitbox) in &layout.display_hunks {
if let Some(hunk_hitbox) = hunk_hitbox { if let Some(hunk_hitbox) = hunk_hitbox
if !self && !self
.editor .editor
.read(cx) .read(cx)
.buffer() .buffer()
.read(cx) .read(cx)
.all_diff_hunks_expanded() .all_diff_hunks_expanded()
{ {
window.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox); window.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox);
}
} }
} }
@ -10152,10 +10147,10 @@ fn compute_auto_height_layout(
let overscroll = size(em_width, px(0.)); let overscroll = size(em_width, px(0.));
let editor_width = text_width - gutter_dimensions.margin - overscroll.width - em_width; let editor_width = text_width - gutter_dimensions.margin - overscroll.width - em_width;
if !matches!(editor.soft_wrap_mode(cx), SoftWrap::None) { if !matches!(editor.soft_wrap_mode(cx), SoftWrap::None)
if editor.set_wrap_width(Some(editor_width), cx) { && editor.set_wrap_width(Some(editor_width), cx)
snapshot = editor.snapshot(window, cx); {
} snapshot = editor.snapshot(window, cx);
} }
let scroll_height = (snapshot.max_point().row().next_row().0 as f32) * line_height; let scroll_height = (snapshot.max_point().row().next_row().0 as f32) * line_height;

View file

@ -312,10 +312,10 @@ impl GitBlame {
.as_ref() .as_ref()
.and_then(|entry| entry.author.as_ref()) .and_then(|entry| entry.author.as_ref())
.map(|author| author.len()); .map(|author| author.len());
if let Some(author_len) = author_len { if let Some(author_len) = author_len
if author_len > max_author_length { && author_len > max_author_length
max_author_length = author_len; {
} max_author_length = author_len;
} }
} }
@ -416,20 +416,19 @@ impl GitBlame {
if row_edits if row_edits
.peek() .peek()
.map_or(true, |next_edit| next_edit.old.start >= old_end) .map_or(true, |next_edit| next_edit.old.start >= old_end)
&& let Some(entry) = cursor.item()
{ {
if let Some(entry) = cursor.item() { if old_end > edit.old.end {
if old_end > edit.old.end { new_entries.push(
new_entries.push( GitBlameEntry {
GitBlameEntry { rows: cursor.end() - edit.old.end,
rows: cursor.end() - edit.old.end, blame: entry.blame.clone(),
blame: entry.blame.clone(), },
}, &(),
&(), );
);
}
cursor.next();
} }
cursor.next();
} }
} }
new_entries.append(cursor.suffix(), &()); new_entries.append(cursor.suffix(), &());

View file

@ -418,24 +418,22 @@ pub fn update_inlay_link_and_hover_points(
} }
if let Some((language_server_id, location)) = if let Some((language_server_id, location)) =
hovered_hint_part.location hovered_hint_part.location
&& secondary_held
&& !editor.has_pending_nonempty_selection()
{ {
if secondary_held go_to_definition_updated = true;
&& !editor.has_pending_nonempty_selection() show_link_definition(
{ shift_held,
go_to_definition_updated = true; editor,
show_link_definition( TriggerPoint::InlayHint(
shift_held, highlight,
editor, location,
TriggerPoint::InlayHint( language_server_id,
highlight, ),
location, snapshot,
language_server_id, window,
), cx,
snapshot, );
window,
cx,
);
}
} }
} }
} }
@ -766,10 +764,11 @@ pub(crate) fn find_url_from_range(
let mut finder = LinkFinder::new(); let mut finder = LinkFinder::new();
finder.kinds(&[LinkKind::Url]); finder.kinds(&[LinkKind::Url]);
if let Some(link) = finder.links(&text).next() { if let Some(link) = finder.links(&text).next()
if link.start() == 0 && link.end() == text.len() { && link.start() == 0
return Some(link.as_str().to_string()); && link.end() == text.len()
} {
return Some(link.as_str().to_string());
} }
None None

View file

@ -142,11 +142,11 @@ pub fn hover_at_inlay(
.info_popovers .info_popovers
.iter() .iter()
.any(|InfoPopover { symbol_range, .. }| { .any(|InfoPopover { symbol_range, .. }| {
if let RangeInEditor::Inlay(range) = symbol_range { if let RangeInEditor::Inlay(range) = symbol_range
if range == &inlay_hover.range { && range == &inlay_hover.range
// Hover triggered from same location as last time. Don't show again. {
return true; // Hover triggered from same location as last time. Don't show again.
} return true;
} }
false false
}) })
@ -270,13 +270,12 @@ fn show_hover(
} }
// Don't request again if the location is the same as the previous request // Don't request again if the location is the same as the previous request
if let Some(triggered_from) = &editor.hover_state.triggered_from { if let Some(triggered_from) = &editor.hover_state.triggered_from
if triggered_from && triggered_from
.cmp(&anchor, &snapshot.buffer_snapshot) .cmp(&anchor, &snapshot.buffer_snapshot)
.is_eq() .is_eq()
{ {
return None; return None;
}
} }
let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay; let hover_popover_delay = EditorSettings::get_global(cx).hover_popover_delay;
@ -717,59 +716,54 @@ pub fn diagnostics_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
} }
pub fn open_markdown_url(link: SharedString, window: &mut Window, cx: &mut App) { pub fn open_markdown_url(link: SharedString, window: &mut Window, cx: &mut App) {
if let Ok(uri) = Url::parse(&link) { if let Ok(uri) = Url::parse(&link)
if uri.scheme() == "file" { && uri.scheme() == "file"
if let Some(workspace) = window.root::<Workspace>().flatten() { && let Some(workspace) = window.root::<Workspace>().flatten()
workspace.update(cx, |workspace, cx| { {
let task = workspace.open_abs_path( workspace.update(cx, |workspace, cx| {
PathBuf::from(uri.path()), let task = workspace.open_abs_path(
OpenOptions { PathBuf::from(uri.path()),
visible: Some(OpenVisible::None), OpenOptions {
..Default::default() visible: Some(OpenVisible::None),
}, ..Default::default()
window, },
cx, window,
); cx,
);
cx.spawn_in(window, async move |_, cx| { cx.spawn_in(window, async move |_, cx| {
let item = task.await?; let item = task.await?;
// Ruby LSP uses URLs with #L1,1-4,4 // Ruby LSP uses URLs with #L1,1-4,4
// we'll just take the first number and assume it's a line number // we'll just take the first number and assume it's a line number
let Some(fragment) = uri.fragment() else { let Some(fragment) = uri.fragment() else {
return anyhow::Ok(()); return anyhow::Ok(());
}; };
let mut accum = 0u32; let mut accum = 0u32;
for c in fragment.chars() { for c in fragment.chars() {
if c >= '0' && c <= '9' && accum < u32::MAX / 2 { if c >= '0' && c <= '9' && accum < u32::MAX / 2 {
accum *= 10; accum *= 10;
accum += c as u32 - '0' as u32; accum += c as u32 - '0' as u32;
} else if accum > 0 { } else if accum > 0 {
break; break;
} }
} }
if accum == 0 { if accum == 0 {
return Ok(()); return Ok(());
} }
let Some(editor) = cx.update(|_, cx| item.act_as::<Editor>(cx))? else { let Some(editor) = cx.update(|_, cx| item.act_as::<Editor>(cx))? else {
return Ok(()); return Ok(());
}; };
editor.update_in(cx, |editor, window, cx| { editor.update_in(cx, |editor, window, cx| {
editor.change_selections( editor.change_selections(Default::default(), window, cx, |selections| {
Default::default(), selections.select_ranges([
window, text::Point::new(accum - 1, 0)..text::Point::new(accum - 1, 0)
cx, ]);
|selections| { });
selections.select_ranges([text::Point::new(accum - 1, 0) })
..text::Point::new(accum - 1, 0)]); })
}, .detach_and_log_err(cx);
); });
}) return;
})
.detach_and_log_err(cx);
});
return;
}
}
} }
cx.open_url(&link); cx.open_url(&link);
} }
@ -839,21 +833,20 @@ impl HoverState {
pub fn focused(&self, window: &mut Window, cx: &mut Context<Editor>) -> bool { pub fn focused(&self, window: &mut Window, cx: &mut Context<Editor>) -> bool {
let mut hover_popover_is_focused = false; let mut hover_popover_is_focused = false;
for info_popover in &self.info_popovers { for info_popover in &self.info_popovers {
if let Some(markdown_view) = &info_popover.parsed_content { if let Some(markdown_view) = &info_popover.parsed_content
if markdown_view.focus_handle(cx).is_focused(window) { && markdown_view.focus_handle(cx).is_focused(window)
hover_popover_is_focused = true;
}
}
}
if let Some(diagnostic_popover) = &self.diagnostic_popover {
if diagnostic_popover
.markdown
.focus_handle(cx)
.is_focused(window)
{ {
hover_popover_is_focused = true; hover_popover_is_focused = true;
} }
} }
if let Some(diagnostic_popover) = &self.diagnostic_popover
&& diagnostic_popover
.markdown
.focus_handle(cx)
.is_focused(window)
{
hover_popover_is_focused = true;
}
hover_popover_is_focused hover_popover_is_focused
} }
} }

View file

@ -168,11 +168,11 @@ pub fn indent_guides_in_range(
while let Some(fold) = folds.next() { while let Some(fold) = folds.next() {
let start = fold.range.start.to_point(&snapshot.buffer_snapshot); let start = fold.range.start.to_point(&snapshot.buffer_snapshot);
let end = fold.range.end.to_point(&snapshot.buffer_snapshot); let end = fold.range.end.to_point(&snapshot.buffer_snapshot);
if let Some(last_range) = fold_ranges.last_mut() { if let Some(last_range) = fold_ranges.last_mut()
if last_range.end >= start { && last_range.end >= start
last_range.end = last_range.end.max(end); {
continue; last_range.end = last_range.end.max(end);
} continue;
} }
fold_ranges.push(start..end); fold_ranges.push(start..end);
} }

View file

@ -498,16 +498,14 @@ impl InlayHintCache {
cmp::Ordering::Less | cmp::Ordering::Equal => { cmp::Ordering::Less | cmp::Ordering::Equal => {
if !old_kinds.contains(&cached_hint.kind) if !old_kinds.contains(&cached_hint.kind)
&& new_kinds.contains(&cached_hint.kind) && new_kinds.contains(&cached_hint.kind)
{ && let Some(anchor) = multi_buffer_snapshot
if let Some(anchor) = multi_buffer_snapshot
.anchor_in_excerpt(*excerpt_id, cached_hint.position) .anchor_in_excerpt(*excerpt_id, cached_hint.position)
{ {
to_insert.push(Inlay::hint( to_insert.push(Inlay::hint(
cached_hint_id.id(), cached_hint_id.id(),
anchor, anchor,
cached_hint, cached_hint,
)); ));
}
} }
excerpt_cache.next(); excerpt_cache.next();
} }
@ -522,16 +520,16 @@ impl InlayHintCache {
for cached_hint_id in excerpt_cache { for cached_hint_id in excerpt_cache {
let maybe_missed_cached_hint = &excerpt_cached_hints.hints_by_id[cached_hint_id]; let maybe_missed_cached_hint = &excerpt_cached_hints.hints_by_id[cached_hint_id];
let cached_hint_kind = maybe_missed_cached_hint.kind; let cached_hint_kind = maybe_missed_cached_hint.kind;
if !old_kinds.contains(&cached_hint_kind) && new_kinds.contains(&cached_hint_kind) { if !old_kinds.contains(&cached_hint_kind)
if let Some(anchor) = multi_buffer_snapshot && new_kinds.contains(&cached_hint_kind)
&& let Some(anchor) = multi_buffer_snapshot
.anchor_in_excerpt(*excerpt_id, maybe_missed_cached_hint.position) .anchor_in_excerpt(*excerpt_id, maybe_missed_cached_hint.position)
{ {
to_insert.push(Inlay::hint( to_insert.push(Inlay::hint(
cached_hint_id.id(), cached_hint_id.id(),
anchor, anchor,
maybe_missed_cached_hint, maybe_missed_cached_hint,
)); ));
}
} }
} }
} }
@ -620,44 +618,44 @@ impl InlayHintCache {
) { ) {
if let Some(excerpt_hints) = self.hints.get(&excerpt_id) { if let Some(excerpt_hints) = self.hints.get(&excerpt_id) {
let mut guard = excerpt_hints.write(); let mut guard = excerpt_hints.write();
if let Some(cached_hint) = guard.hints_by_id.get_mut(&id) { if let Some(cached_hint) = guard.hints_by_id.get_mut(&id)
if let ResolveState::CanResolve(server_id, _) = &cached_hint.resolve_state { && let ResolveState::CanResolve(server_id, _) = &cached_hint.resolve_state
let hint_to_resolve = cached_hint.clone(); {
let server_id = *server_id; let hint_to_resolve = cached_hint.clone();
cached_hint.resolve_state = ResolveState::Resolving; let server_id = *server_id;
drop(guard); cached_hint.resolve_state = ResolveState::Resolving;
cx.spawn_in(window, async move |editor, cx| { drop(guard);
let resolved_hint_task = editor.update(cx, |editor, cx| { cx.spawn_in(window, async move |editor, cx| {
let buffer = editor.buffer().read(cx).buffer(buffer_id)?; let resolved_hint_task = editor.update(cx, |editor, cx| {
editor.semantics_provider.as_ref()?.resolve_inlay_hint( let buffer = editor.buffer().read(cx).buffer(buffer_id)?;
hint_to_resolve, editor.semantics_provider.as_ref()?.resolve_inlay_hint(
buffer, hint_to_resolve,
server_id, buffer,
cx, server_id,
) cx,
})?; )
if let Some(resolved_hint_task) = resolved_hint_task { })?;
let mut resolved_hint = if let Some(resolved_hint_task) = resolved_hint_task {
resolved_hint_task.await.context("hint resolve task")?; let mut resolved_hint =
editor.read_with(cx, |editor, _| { resolved_hint_task.await.context("hint resolve task")?;
if let Some(excerpt_hints) = editor.read_with(cx, |editor, _| {
editor.inlay_hint_cache.hints.get(&excerpt_id) if let Some(excerpt_hints) =
editor.inlay_hint_cache.hints.get(&excerpt_id)
{
let mut guard = excerpt_hints.write();
if let Some(cached_hint) = guard.hints_by_id.get_mut(&id)
&& cached_hint.resolve_state == ResolveState::Resolving
{ {
let mut guard = excerpt_hints.write(); resolved_hint.resolve_state = ResolveState::Resolved;
if let Some(cached_hint) = guard.hints_by_id.get_mut(&id) { *cached_hint = resolved_hint;
if cached_hint.resolve_state == ResolveState::Resolving {
resolved_hint.resolve_state = ResolveState::Resolved;
*cached_hint = resolved_hint;
}
}
} }
})?; }
} })?;
}
anyhow::Ok(()) anyhow::Ok(())
}) })
.detach_and_log_err(cx); .detach_and_log_err(cx);
}
} }
} }
} }
@ -990,8 +988,8 @@ fn fetch_and_update_hints(
let buffer = editor.buffer().read(cx).buffer(query.buffer_id)?; let buffer = editor.buffer().read(cx).buffer(query.buffer_id)?;
if !editor.registered_buffers.contains_key(&query.buffer_id) { if !editor.registered_buffers.contains_key(&query.buffer_id)
if let Some(project) = editor.project.as_ref() { && let Some(project) = editor.project.as_ref() {
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
editor.registered_buffers.insert( editor.registered_buffers.insert(
query.buffer_id, query.buffer_id,
@ -999,7 +997,6 @@ fn fetch_and_update_hints(
); );
}) })
} }
}
editor editor
.semantics_provider .semantics_provider
@ -1240,14 +1237,12 @@ fn apply_hint_update(
.inlay_hint_cache .inlay_hint_cache
.allowed_hint_kinds .allowed_hint_kinds
.contains(&new_hint.kind) .contains(&new_hint.kind)
{ && let Some(new_hint_position) =
if let Some(new_hint_position) =
multi_buffer_snapshot.anchor_in_excerpt(query.excerpt_id, new_hint.position) multi_buffer_snapshot.anchor_in_excerpt(query.excerpt_id, new_hint.position)
{ {
splice splice
.to_insert .to_insert
.push(Inlay::hint(new_inlay_id, new_hint_position, &new_hint)); .push(Inlay::hint(new_inlay_id, new_hint_position, &new_hint));
}
} }
let new_id = InlayId::Hint(new_inlay_id); let new_id = InlayId::Hint(new_inlay_id);
cached_excerpt_hints.hints_by_id.insert(new_id, new_hint); cached_excerpt_hints.hints_by_id.insert(new_id, new_hint);

View file

@ -930,10 +930,10 @@ impl Item for Editor {
})?; })?;
buffer buffer
.update(cx, |buffer, cx| { .update(cx, |buffer, cx| {
if let Some(transaction) = transaction { if let Some(transaction) = transaction
if !buffer.is_singleton() { && !buffer.is_singleton()
buffer.push_transaction(&transaction.0, cx); {
} buffer.push_transaction(&transaction.0, cx);
} }
}) })
.ok(); .ok();
@ -1374,36 +1374,33 @@ impl ProjectItem for Editor {
let mut editor = Self::for_buffer(buffer.clone(), Some(project), window, cx); let mut editor = Self::for_buffer(buffer.clone(), Some(project), window, cx);
if let Some((excerpt_id, buffer_id, snapshot)) = if let Some((excerpt_id, buffer_id, snapshot)) =
editor.buffer().read(cx).snapshot(cx).as_singleton() editor.buffer().read(cx).snapshot(cx).as_singleton()
&& WorkspaceSettings::get(None, cx).restore_on_file_reopen
&& let Some(restoration_data) = Self::project_item_kind()
.and_then(|kind| pane.as_ref()?.project_item_restoration_data.get(&kind))
.and_then(|data| data.downcast_ref::<EditorRestorationData>())
.and_then(|data| {
let file = project::File::from_dyn(buffer.read(cx).file())?;
data.entries.get(&file.abs_path(cx))
})
{ {
if WorkspaceSettings::get(None, cx).restore_on_file_reopen { editor.fold_ranges(
if let Some(restoration_data) = Self::project_item_kind() clip_ranges(&restoration_data.folds, snapshot),
.and_then(|kind| pane.as_ref()?.project_item_restoration_data.get(&kind)) false,
.and_then(|data| data.downcast_ref::<EditorRestorationData>()) window,
.and_then(|data| { cx,
let file = project::File::from_dyn(buffer.read(cx).file())?; );
data.entries.get(&file.abs_path(cx)) if !restoration_data.selections.is_empty() {
}) editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
{ s.select_ranges(clip_ranges(&restoration_data.selections, snapshot));
editor.fold_ranges( });
clip_ranges(&restoration_data.folds, snapshot),
false,
window,
cx,
);
if !restoration_data.selections.is_empty() {
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
s.select_ranges(clip_ranges(&restoration_data.selections, snapshot));
});
}
let (top_row, offset) = restoration_data.scroll_position;
let anchor = Anchor::in_buffer(
*excerpt_id,
buffer_id,
snapshot.anchor_before(Point::new(top_row, 0)),
);
editor.set_scroll_anchor(ScrollAnchor { anchor, offset }, window, cx);
}
} }
let (top_row, offset) = restoration_data.scroll_position;
let anchor = Anchor::in_buffer(
*excerpt_id,
buffer_id,
snapshot.anchor_before(Point::new(top_row, 0)),
);
editor.set_scroll_anchor(ScrollAnchor { anchor, offset }, window, cx);
} }
editor editor

View file

@ -51,12 +51,11 @@ pub(crate) fn should_auto_close(
continue; continue;
}; };
let mut jsx_open_tag_node = node; let mut jsx_open_tag_node = node;
if node.grammar_name() != config.open_tag_node_name { if node.grammar_name() != config.open_tag_node_name
if let Some(parent) = node.parent() { && let Some(parent) = node.parent()
if parent.grammar_name() == config.open_tag_node_name { && parent.grammar_name() == config.open_tag_node_name
jsx_open_tag_node = parent; {
} jsx_open_tag_node = parent;
}
} }
if jsx_open_tag_node.grammar_name() != config.open_tag_node_name { if jsx_open_tag_node.grammar_name() != config.open_tag_node_name {
continue; continue;
@ -284,10 +283,8 @@ pub(crate) fn generate_auto_close_edits(
unclosed_open_tag_count -= 1; unclosed_open_tag_count -= 1;
} }
} else if has_erroneous_close_tag && kind == erroneous_close_tag_node_name { } else if has_erroneous_close_tag && kind == erroneous_close_tag_node_name {
if tag_node_name_equals(&node, &tag_name) { if tag_node_name_equals(&node, &tag_name) && !is_after_open_tag(&node) {
if !is_after_open_tag(&node) { unclosed_open_tag_count -= 1;
unclosed_open_tag_count -= 1;
}
} }
} else if kind == config.jsx_element_node_name { } else if kind == config.jsx_element_node_name {
// perf: filter only open,close,element,erroneous nodes // perf: filter only open,close,element,erroneous nodes

View file

@ -147,16 +147,15 @@ pub fn lsp_tasks(
}, },
cx, cx,
) )
}) { }) && let Some(new_runnables) = runnables_task.await.log_err()
if let Some(new_runnables) = runnables_task.await.log_err() { {
new_lsp_tasks.extend(new_runnables.runnables.into_iter().filter_map( new_lsp_tasks.extend(new_runnables.runnables.into_iter().filter_map(
|(location, runnable)| { |(location, runnable)| {
let resolved_task = let resolved_task =
runnable.resolve_task(&id_base, &lsp_buffer_context)?; runnable.resolve_task(&id_base, &lsp_buffer_context)?;
Some((location, resolved_task)) Some((location, resolved_task))
}, },
)); ));
}
} }
lsp_tasks lsp_tasks
.entry(source_kind) .entry(source_kind)

View file

@ -510,10 +510,10 @@ pub fn find_preceding_boundary_point(
if find_range == FindRange::SingleLine && ch == '\n' { if find_range == FindRange::SingleLine && ch == '\n' {
break; break;
} }
if let Some(prev_ch) = prev_ch { if let Some(prev_ch) = prev_ch
if is_boundary(ch, prev_ch) { && is_boundary(ch, prev_ch)
break; {
} break;
} }
offset -= ch.len_utf8(); offset -= ch.len_utf8();
@ -562,13 +562,13 @@ pub fn find_boundary_point(
if find_range == FindRange::SingleLine && ch == '\n' { if find_range == FindRange::SingleLine && ch == '\n' {
break; break;
} }
if let Some(prev_ch) = prev_ch { if let Some(prev_ch) = prev_ch
if is_boundary(prev_ch, ch) { && is_boundary(prev_ch, ch)
if return_point_before_boundary { {
return map.clip_point(prev_offset.to_display_point(map), Bias::Right); if return_point_before_boundary {
} else { return map.clip_point(prev_offset.to_display_point(map), Bias::Right);
break; } else {
} break;
} }
} }
prev_offset = offset; prev_offset = offset;
@ -603,13 +603,13 @@ pub fn find_preceding_boundary_trail(
// Find the boundary // Find the boundary
let start_offset = offset; let start_offset = offset;
for ch in forward { for ch in forward {
if let Some(prev_ch) = prev_ch { if let Some(prev_ch) = prev_ch
if is_boundary(prev_ch, ch) { && is_boundary(prev_ch, ch)
if start_offset == offset { {
trail_offset = Some(offset); if start_offset == offset {
} else { trail_offset = Some(offset);
break; } else {
} break;
} }
} }
offset -= ch.len_utf8(); offset -= ch.len_utf8();
@ -651,13 +651,13 @@ pub fn find_boundary_trail(
// Find the boundary // Find the boundary
let start_offset = offset; let start_offset = offset;
for ch in forward { for ch in forward {
if let Some(prev_ch) = prev_ch { if let Some(prev_ch) = prev_ch
if is_boundary(prev_ch, ch) { && is_boundary(prev_ch, ch)
if start_offset == offset { {
trail_offset = Some(offset); if start_offset == offset {
} else { trail_offset = Some(offset);
break; } else {
} break;
} }
} }
offset += ch.len_utf8(); offset += ch.len_utf8();

View file

@ -285,11 +285,11 @@ pub fn open_docs(editor: &mut Editor, _: &OpenDocs, window: &mut Window, cx: &mu
workspace.update(cx, |_workspace, cx| { workspace.update(cx, |_workspace, cx| {
// Check if the local document exists, otherwise fallback to the online document. // Check if the local document exists, otherwise fallback to the online document.
// Open with the default browser. // Open with the default browser.
if let Some(local_url) = docs_urls.local { if let Some(local_url) = docs_urls.local
if fs::metadata(Path::new(&local_url[8..])).is_ok() { && fs::metadata(Path::new(&local_url[8..])).is_ok()
cx.open_url(&local_url); {
return; cx.open_url(&local_url);
} return;
} }
if let Some(web_url) = docs_urls.web { if let Some(web_url) = docs_urls.web {

View file

@ -703,20 +703,20 @@ impl Editor {
if matches!( if matches!(
settings.defaults.soft_wrap, settings.defaults.soft_wrap,
SoftWrap::PreferredLineLength | SoftWrap::Bounded SoftWrap::PreferredLineLength | SoftWrap::Bounded
) { ) && (settings.defaults.preferred_line_length as f32) < visible_column_count
if (settings.defaults.preferred_line_length as f32) < visible_column_count { {
visible_column_count = settings.defaults.preferred_line_length as f32; visible_column_count = settings.defaults.preferred_line_length as f32;
}
} }
// If the scroll position is currently at the left edge of the document // If the scroll position is currently at the left edge of the document
// (x == 0.0) and the intent is to scroll right, the gutter's margin // (x == 0.0) and the intent is to scroll right, the gutter's margin
// should first be added to the current position, otherwise the cursor // should first be added to the current position, otherwise the cursor
// will end at the column position minus the margin, which looks off. // will end at the column position minus the margin, which looks off.
if current_position.x == 0.0 && amount.columns(visible_column_count) > 0. { if current_position.x == 0.0
if let Some(last_position_map) = &self.last_position_map { && amount.columns(visible_column_count) > 0.
current_position.x += self.gutter_dimensions.margin / last_position_map.em_advance; && let Some(last_position_map) = &self.last_position_map
} {
current_position.x += self.gutter_dimensions.margin / last_position_map.em_advance;
} }
let new_position = current_position let new_position = current_position
+ point( + point(
@ -749,12 +749,10 @@ impl Editor {
if let (Some(visible_lines), Some(visible_columns)) = if let (Some(visible_lines), Some(visible_columns)) =
(self.visible_line_count(), self.visible_column_count()) (self.visible_line_count(), self.visible_column_count())
&& newest_head.row() <= DisplayRow(screen_top.row().0 + visible_lines as u32)
&& newest_head.column() <= screen_top.column() + visible_columns as u32
{ {
if newest_head.row() <= DisplayRow(screen_top.row().0 + visible_lines as u32) return Ordering::Equal;
&& newest_head.column() <= screen_top.column() + visible_columns as u32
{
return Ordering::Equal;
}
} }
Ordering::Greater Ordering::Greater

View file

@ -116,12 +116,12 @@ impl Editor {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut scroll_position = self.scroll_manager.scroll_position(&display_map); let mut scroll_position = self.scroll_manager.scroll_position(&display_map);
let original_y = scroll_position.y; let original_y = scroll_position.y;
if let Some(last_bounds) = self.expect_bounds_change.take() { if let Some(last_bounds) = self.expect_bounds_change.take()
if scroll_position.y != 0. { && scroll_position.y != 0.
scroll_position.y += (bounds.top() - last_bounds.top()) / line_height; {
if scroll_position.y < 0. { scroll_position.y += (bounds.top() - last_bounds.top()) / line_height;
scroll_position.y = 0.; if scroll_position.y < 0. {
} scroll_position.y = 0.;
} }
} }
if scroll_position.y > max_scroll_top { if scroll_position.y > max_scroll_top {

View file

@ -184,10 +184,10 @@ pub fn editor_content_with_blocks(editor: &Entity<Editor>, cx: &mut VisualTestCo
for (row, block) in blocks { for (row, block) in blocks {
match block { match block {
Block::Custom(custom_block) => { Block::Custom(custom_block) => {
if let BlockPlacement::Near(x) = &custom_block.placement { if let BlockPlacement::Near(x) = &custom_block.placement
if snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot)) { && snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot))
continue; {
} continue;
}; };
let content = block_content_for_tests(editor, custom_block.id, cx) let content = block_content_for_tests(editor, custom_block.id, cx)
.expect("block content not found"); .expect("block content not found");

View file

@ -167,15 +167,14 @@ fn main() {
continue; continue;
} }
if let Some(language) = meta.language_server { if let Some(language) = meta.language_server
if !languages.contains(&language.file_extension) { && !languages.contains(&language.file_extension) {
panic!( panic!(
"Eval for {:?} could not be run because no language server was found for extension {:?}", "Eval for {:?} could not be run because no language server was found for extension {:?}",
meta.name, meta.name,
language.file_extension language.file_extension
); );
} }
}
// TODO: This creates a worktree per repetition. Ideally these examples should // TODO: This creates a worktree per repetition. Ideally these examples should
// either be run sequentially on the same worktree, or reuse worktrees when there // either be run sequentially on the same worktree, or reuse worktrees when there

View file

@ -46,27 +46,25 @@ fn find_target_files_recursive(
max_depth, max_depth,
found_files, found_files,
)?; )?;
} else if path.is_file() { } else if path.is_file()
if let Some(filename_osstr) = path.file_name() { && let Some(filename_osstr) = path.file_name()
if let Some(filename_str) = filename_osstr.to_str() { && let Some(filename_str) = filename_osstr.to_str()
if filename_str == target_filename { && filename_str == target_filename
found_files.push(path); {
} found_files.push(path);
}
}
} }
} }
Ok(()) Ok(())
} }
pub fn generate_explorer_html(input_paths: &[PathBuf], output_path: &PathBuf) -> Result<String> { pub fn generate_explorer_html(input_paths: &[PathBuf], output_path: &PathBuf) -> Result<String> {
if let Some(parent) = output_path.parent() { if let Some(parent) = output_path.parent()
if !parent.exists() { && !parent.exists()
fs::create_dir_all(parent).context(format!( {
"Failed to create output directory: {}", fs::create_dir_all(parent).context(format!(
parent.display() "Failed to create output directory: {}",
))?; parent.display()
} ))?;
} }
let template_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/explorer.html"); let template_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/explorer.html");

View file

@ -376,11 +376,10 @@ impl ExampleInstance {
); );
let result = this.thread.conversation(&mut example_cx).await; let result = this.thread.conversation(&mut example_cx).await;
if let Err(err) = result { if let Err(err) = result
if !err.is::<FailedAssertion>() { && !err.is::<FailedAssertion>() {
return Err(err); return Err(err);
} }
}
println!("{}Stopped", this.log_prefix); println!("{}Stopped", this.log_prefix);

View file

@ -178,16 +178,15 @@ pub fn parse_wasm_extension_version(
for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) { for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) {
if let wasmparser::Payload::CustomSection(s) = if let wasmparser::Payload::CustomSection(s) =
part.context("error parsing wasm extension")? part.context("error parsing wasm extension")?
&& s.name() == "zed:api-version"
{ {
if s.name() == "zed:api-version" { version = parse_wasm_extension_version_custom_section(s.data());
version = parse_wasm_extension_version_custom_section(s.data()); if version.is_none() {
if version.is_none() { bail!(
bail!( "extension {} has invalid zed:api-version section: {:?}",
"extension {} has invalid zed:api-version section: {:?}", extension_id,
extension_id, s.data()
s.data() );
);
}
} }
} }
} }

View file

@ -93,10 +93,9 @@ pub fn is_version_compatible(
.wasm_api_version .wasm_api_version
.as_ref() .as_ref()
.and_then(|wasm_api_version| SemanticVersion::from_str(wasm_api_version).ok()) .and_then(|wasm_api_version| SemanticVersion::from_str(wasm_api_version).ok())
&& !is_supported_wasm_api_version(release_channel, wasm_api_version)
{ {
if !is_supported_wasm_api_version(release_channel, wasm_api_version) { return false;
return false;
}
} }
true true
@ -292,19 +291,17 @@ impl ExtensionStore {
// it must be asynchronously rebuilt. // it must be asynchronously rebuilt.
let mut extension_index = ExtensionIndex::default(); let mut extension_index = ExtensionIndex::default();
let mut extension_index_needs_rebuild = true; let mut extension_index_needs_rebuild = true;
if let Ok(index_content) = index_content { if let Ok(index_content) = index_content
if let Some(index) = serde_json::from_str(&index_content).log_err() { && let Some(index) = serde_json::from_str(&index_content).log_err()
extension_index = index; {
if let (Ok(Some(index_metadata)), Ok(Some(extensions_metadata))) = extension_index = index;
(index_metadata, extensions_metadata) if let (Ok(Some(index_metadata)), Ok(Some(extensions_metadata))) =
{ (index_metadata, extensions_metadata)
if index_metadata && index_metadata
.mtime .mtime
.bad_is_greater_than(extensions_metadata.mtime) .bad_is_greater_than(extensions_metadata.mtime)
{ {
extension_index_needs_rebuild = false; extension_index_needs_rebuild = false;
}
}
} }
} }
@ -392,10 +389,9 @@ impl ExtensionStore {
if let Some(path::Component::Normal(extension_dir_name)) = if let Some(path::Component::Normal(extension_dir_name)) =
event_path.components().next() event_path.components().next()
&& let Some(extension_id) = extension_dir_name.to_str()
{ {
if let Some(extension_id) = extension_dir_name.to_str() { reload_tx.unbounded_send(Some(extension_id.into())).ok();
reload_tx.unbounded_send(Some(extension_id.into())).ok();
}
} }
} }
} }
@ -763,8 +759,8 @@ impl ExtensionStore {
if let ExtensionOperation::Install = operation { if let ExtensionOperation::Install = operation {
this.update( cx, |this, cx| { this.update( cx, |this, cx| {
cx.emit(Event::ExtensionInstalled(extension_id.clone())); cx.emit(Event::ExtensionInstalled(extension_id.clone()));
if let Some(events) = ExtensionEvents::try_global(cx) { if let Some(events) = ExtensionEvents::try_global(cx)
if let Some(manifest) = this.extension_manifest_for_id(&extension_id) { && let Some(manifest) = this.extension_manifest_for_id(&extension_id) {
events.update(cx, |this, cx| { events.update(cx, |this, cx| {
this.emit( this.emit(
extension::Event::ExtensionInstalled(manifest.clone()), extension::Event::ExtensionInstalled(manifest.clone()),
@ -772,7 +768,6 @@ impl ExtensionStore {
) )
}); });
} }
}
}) })
.ok(); .ok();
} }
@ -912,12 +907,12 @@ impl ExtensionStore {
extension_store.update(cx, |_, cx| { extension_store.update(cx, |_, cx| {
cx.emit(Event::ExtensionUninstalled(extension_id.clone())); cx.emit(Event::ExtensionUninstalled(extension_id.clone()));
if let Some(events) = ExtensionEvents::try_global(cx) { if let Some(events) = ExtensionEvents::try_global(cx)
if let Some(manifest) = extension_manifest { && let Some(manifest) = extension_manifest
events.update(cx, |this, cx| { {
this.emit(extension::Event::ExtensionUninstalled(manifest.clone()), cx) events.update(cx, |this, cx| {
}); this.emit(extension::Event::ExtensionUninstalled(manifest.clone()), cx)
} });
} }
})?; })?;
@ -997,12 +992,12 @@ impl ExtensionStore {
this.update(cx, |this, cx| this.reload(None, cx))?.await; this.update(cx, |this, cx| this.reload(None, cx))?.await;
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
cx.emit(Event::ExtensionInstalled(extension_id.clone())); cx.emit(Event::ExtensionInstalled(extension_id.clone()));
if let Some(events) = ExtensionEvents::try_global(cx) { if let Some(events) = ExtensionEvents::try_global(cx)
if let Some(manifest) = this.extension_manifest_for_id(&extension_id) { && let Some(manifest) = this.extension_manifest_for_id(&extension_id)
events.update(cx, |this, cx| { {
this.emit(extension::Event::ExtensionInstalled(manifest.clone()), cx) events.update(cx, |this, cx| {
}); this.emit(extension::Event::ExtensionInstalled(manifest.clone()), cx)
} });
} }
})?; })?;
@ -1788,10 +1783,10 @@ impl ExtensionStore {
let connection_options = client.read(cx).connection_options(); let connection_options = client.read(cx).connection_options();
let ssh_url = connection_options.ssh_url(); let ssh_url = connection_options.ssh_url();
if let Some(existing_client) = self.ssh_clients.get(&ssh_url) { if let Some(existing_client) = self.ssh_clients.get(&ssh_url)
if existing_client.upgrade().is_some() { && existing_client.upgrade().is_some()
return; {
} return;
} }
self.ssh_clients.insert(ssh_url, client.downgrade()); self.ssh_clients.insert(ssh_url, client.downgrade());

View file

@ -701,16 +701,15 @@ pub fn parse_wasm_extension_version(
for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) { for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) {
if let wasmparser::Payload::CustomSection(s) = if let wasmparser::Payload::CustomSection(s) =
part.context("error parsing wasm extension")? part.context("error parsing wasm extension")?
&& s.name() == "zed:api-version"
{ {
if s.name() == "zed:api-version" { version = parse_wasm_extension_version_custom_section(s.data());
version = parse_wasm_extension_version_custom_section(s.data()); if version.is_none() {
if version.is_none() { bail!(
bail!( "extension {} has invalid zed:api-version section: {:?}",
"extension {} has invalid zed:api-version section: {:?}", extension_id,
extension_id, s.data()
s.data() );
);
}
} }
} }
} }

View file

@ -1031,15 +1031,14 @@ impl ExtensionsPage {
.read(cx) .read(cx)
.extension_manifest_for_id(&extension_id) .extension_manifest_for_id(&extension_id)
.cloned() .cloned()
&& let Some(events) = extension::ExtensionEvents::try_global(cx)
{ {
if let Some(events) = extension::ExtensionEvents::try_global(cx) { events.update(cx, |this, cx| {
events.update(cx, |this, cx| { this.emit(
this.emit( extension::Event::ConfigureExtensionRequested(manifest),
extension::Event::ConfigureExtensionRequested(manifest), cx,
cx, )
) });
});
}
} }
} }
}) })

View file

@ -209,11 +209,11 @@ impl FileFinder {
let Some(init_modifiers) = self.init_modifiers.take() else { let Some(init_modifiers) = self.init_modifiers.take() else {
return; return;
}; };
if self.picker.read(cx).delegate.has_changed_selected_index { if self.picker.read(cx).delegate.has_changed_selected_index
if !event.modified() || !init_modifiers.is_subset_of(event) { && (!event.modified() || !init_modifiers.is_subset_of(event))
self.init_modifiers = None; {
window.dispatch_action(menu::Confirm.boxed_clone(), cx); self.init_modifiers = None;
} window.dispatch_action(menu::Confirm.boxed_clone(), cx);
} }
} }
@ -323,27 +323,27 @@ impl FileFinder {
) { ) {
self.picker.update(cx, |picker, cx| { self.picker.update(cx, |picker, cx| {
let delegate = &mut picker.delegate; let delegate = &mut picker.delegate;
if let Some(workspace) = delegate.workspace.upgrade() { if let Some(workspace) = delegate.workspace.upgrade()
if let Some(m) = delegate.matches.get(delegate.selected_index()) { && let Some(m) = delegate.matches.get(delegate.selected_index())
let path = match &m { {
Match::History { path, .. } => { let path = match &m {
let worktree_id = path.project.worktree_id; Match::History { path, .. } => {
ProjectPath { let worktree_id = path.project.worktree_id;
worktree_id, ProjectPath {
path: Arc::clone(&path.project.path), worktree_id,
} path: Arc::clone(&path.project.path),
} }
Match::Search(m) => ProjectPath { }
worktree_id: WorktreeId::from_usize(m.0.worktree_id), Match::Search(m) => ProjectPath {
path: m.0.path.clone(), worktree_id: WorktreeId::from_usize(m.0.worktree_id),
}, path: m.0.path.clone(),
Match::CreateNew(p) => p.clone(), },
}; Match::CreateNew(p) => p.clone(),
let open_task = workspace.update(cx, move |workspace, cx| { };
workspace.split_path_preview(path, false, Some(split_direction), window, cx) let open_task = workspace.update(cx, move |workspace, cx| {
}); workspace.split_path_preview(path, false, Some(split_direction), window, cx)
open_task.detach_and_log_err(cx); });
} open_task.detach_and_log_err(cx);
} }
}) })
} }
@ -675,17 +675,17 @@ impl Matches {
let path_str = panel_match.0.path.to_string_lossy(); let path_str = panel_match.0.path.to_string_lossy();
let filename_str = filename.to_string_lossy(); let filename_str = filename.to_string_lossy();
if let Some(filename_pos) = path_str.rfind(&*filename_str) { if let Some(filename_pos) = path_str.rfind(&*filename_str)
if panel_match.0.positions[0] >= filename_pos { && panel_match.0.positions[0] >= filename_pos
let mut prev_position = panel_match.0.positions[0]; {
for p in &panel_match.0.positions[1..] { let mut prev_position = panel_match.0.positions[0];
if *p != prev_position + 1 { for p in &panel_match.0.positions[1..] {
return false; if *p != prev_position + 1 {
} return false;
prev_position = *p;
} }
return true; prev_position = *p;
} }
return true;
} }
} }
@ -1045,10 +1045,10 @@ impl FileFinderDelegate {
) )
} else { } else {
let mut path = Arc::clone(project_relative_path); let mut path = Arc::clone(project_relative_path);
if project_relative_path.as_ref() == Path::new("") { if project_relative_path.as_ref() == Path::new("")
if let Some(absolute_path) = &entry_path.absolute { && let Some(absolute_path) = &entry_path.absolute
path = Arc::from(absolute_path.as_path()); {
} path = Arc::from(absolute_path.as_path());
} }
let mut path_match = PathMatch { let mut path_match = PathMatch {
@ -1078,23 +1078,21 @@ impl FileFinderDelegate {
), ),
}; };
if file_name_positions.is_empty() { if file_name_positions.is_empty()
if let Some(user_home_path) = std::env::var("HOME").ok() { && let Some(user_home_path) = std::env::var("HOME").ok()
let user_home_path = user_home_path.trim(); {
if !user_home_path.is_empty() { let user_home_path = user_home_path.trim();
if full_path.starts_with(user_home_path) { if !user_home_path.is_empty() && full_path.starts_with(user_home_path) {
full_path.replace_range(0..user_home_path.len(), "~"); full_path.replace_range(0..user_home_path.len(), "~");
full_path_positions.retain_mut(|pos| { full_path_positions.retain_mut(|pos| {
if *pos >= user_home_path.len() { if *pos >= user_home_path.len() {
*pos -= user_home_path.len(); *pos -= user_home_path.len();
*pos += 1; *pos += 1;
true true
} else { } else {
false false
}
})
} }
} })
} }
} }
@ -1242,14 +1240,13 @@ impl FileFinderDelegate {
/// Skips first history match (that is displayed topmost) if it's currently opened. /// Skips first history match (that is displayed topmost) if it's currently opened.
fn calculate_selected_index(&self, cx: &mut Context<Picker<Self>>) -> usize { fn calculate_selected_index(&self, cx: &mut Context<Picker<Self>>) -> usize {
if FileFinderSettings::get_global(cx).skip_focus_for_active_in_search { if FileFinderSettings::get_global(cx).skip_focus_for_active_in_search
if let Some(Match::History { path, .. }) = self.matches.get(0) { && let Some(Match::History { path, .. }) = self.matches.get(0)
if Some(path) == self.currently_opened_path.as_ref() { && Some(path) == self.currently_opened_path.as_ref()
let elements_after_first = self.matches.len() - 1; {
if elements_after_first > 0 { let elements_after_first = self.matches.len() - 1;
return 1; if elements_after_first > 0 {
} return 1;
}
} }
} }
@ -1310,10 +1307,10 @@ impl PickerDelegate for FileFinderDelegate {
.enumerate() .enumerate()
.find(|(_, m)| !matches!(m, Match::History { .. })) .find(|(_, m)| !matches!(m, Match::History { .. }))
.map(|(i, _)| i); .map(|(i, _)| i);
if let Some(first_non_history_index) = first_non_history_index { if let Some(first_non_history_index) = first_non_history_index
if first_non_history_index > 0 { && first_non_history_index > 0
return vec![first_non_history_index - 1]; {
} return vec![first_non_history_index - 1];
} }
} }
Vec::new() Vec::new()
@ -1436,69 +1433,101 @@ impl PickerDelegate for FileFinderDelegate {
window: &mut Window, window: &mut Window,
cx: &mut Context<Picker<FileFinderDelegate>>, cx: &mut Context<Picker<FileFinderDelegate>>,
) { ) {
if let Some(m) = self.matches.get(self.selected_index()) { if let Some(m) = self.matches.get(self.selected_index())
if let Some(workspace) = self.workspace.upgrade() { && let Some(workspace) = self.workspace.upgrade()
let open_task = workspace.update(cx, |workspace, cx| { {
let split_or_open = let open_task = workspace.update(cx, |workspace, cx| {
|workspace: &mut Workspace, let split_or_open =
project_path, |workspace: &mut Workspace,
window: &mut Window, project_path,
cx: &mut Context<Workspace>| { window: &mut Window,
let allow_preview = cx: &mut Context<Workspace>| {
PreviewTabsSettings::get_global(cx).enable_preview_from_file_finder; let allow_preview =
if secondary { PreviewTabsSettings::get_global(cx).enable_preview_from_file_finder;
workspace.split_path_preview( if secondary {
project_path, workspace.split_path_preview(
allow_preview, project_path,
None, allow_preview,
window, None,
cx, window,
) cx,
} else { )
workspace.open_path_preview( } else {
project_path, workspace.open_path_preview(
None, project_path,
true, None,
allow_preview, true,
true, allow_preview,
window, true,
cx, window,
) cx,
} )
};
match &m {
Match::CreateNew(project_path) => {
// Create a new file with the given filename
if secondary {
workspace.split_path_preview(
project_path.clone(),
false,
None,
window,
cx,
)
} else {
workspace.open_path_preview(
project_path.clone(),
None,
true,
false,
true,
window,
cx,
)
}
} }
};
match &m {
Match::CreateNew(project_path) => {
// Create a new file with the given filename
if secondary {
workspace.split_path_preview(
project_path.clone(),
false,
None,
window,
cx,
)
} else {
workspace.open_path_preview(
project_path.clone(),
None,
true,
false,
true,
window,
cx,
)
}
}
Match::History { path, .. } => { Match::History { path, .. } => {
let worktree_id = path.project.worktree_id; let worktree_id = path.project.worktree_id;
if workspace if workspace
.project() .project()
.read(cx) .read(cx)
.worktree_for_id(worktree_id, cx) .worktree_for_id(worktree_id, cx)
.is_some() .is_some()
{ {
split_or_open( split_or_open(
workspace,
ProjectPath {
worktree_id,
path: Arc::clone(&path.project.path),
},
window,
cx,
)
} else {
match path.absolute.as_ref() {
Some(abs_path) => {
if secondary {
workspace.split_abs_path(
abs_path.to_path_buf(),
false,
window,
cx,
)
} else {
workspace.open_abs_path(
abs_path.to_path_buf(),
OpenOptions {
visible: Some(OpenVisible::None),
..Default::default()
},
window,
cx,
)
}
}
None => split_or_open(
workspace, workspace,
ProjectPath { ProjectPath {
worktree_id, worktree_id,
@ -1506,88 +1535,52 @@ impl PickerDelegate for FileFinderDelegate {
}, },
window, window,
cx, cx,
) ),
} else {
match path.absolute.as_ref() {
Some(abs_path) => {
if secondary {
workspace.split_abs_path(
abs_path.to_path_buf(),
false,
window,
cx,
)
} else {
workspace.open_abs_path(
abs_path.to_path_buf(),
OpenOptions {
visible: Some(OpenVisible::None),
..Default::default()
},
window,
cx,
)
}
}
None => split_or_open(
workspace,
ProjectPath {
worktree_id,
path: Arc::clone(&path.project.path),
},
window,
cx,
),
}
} }
} }
Match::Search(m) => split_or_open(
workspace,
ProjectPath {
worktree_id: WorktreeId::from_usize(m.0.worktree_id),
path: m.0.path.clone(),
},
window,
cx,
),
} }
}); Match::Search(m) => split_or_open(
workspace,
ProjectPath {
worktree_id: WorktreeId::from_usize(m.0.worktree_id),
path: m.0.path.clone(),
},
window,
cx,
),
}
});
let row = self let row = self
.latest_search_query .latest_search_query
.as_ref() .as_ref()
.and_then(|query| query.path_position.row) .and_then(|query| query.path_position.row)
.map(|row| row.saturating_sub(1)); .map(|row| row.saturating_sub(1));
let col = self let col = self
.latest_search_query .latest_search_query
.as_ref() .as_ref()
.and_then(|query| query.path_position.column) .and_then(|query| query.path_position.column)
.unwrap_or(0) .unwrap_or(0)
.saturating_sub(1); .saturating_sub(1);
let finder = self.file_finder.clone(); let finder = self.file_finder.clone();
cx.spawn_in(window, async move |_, cx| { cx.spawn_in(window, async move |_, cx| {
let item = open_task.await.notify_async_err(cx)?; let item = open_task.await.notify_async_err(cx)?;
if let Some(row) = row { if let Some(row) = row
if let Some(active_editor) = item.downcast::<Editor>() { && let Some(active_editor) = item.downcast::<Editor>()
active_editor {
.downgrade() active_editor
.update_in(cx, |editor, window, cx| { .downgrade()
editor.go_to_singleton_buffer_point( .update_in(cx, |editor, window, cx| {
Point::new(row, col), editor.go_to_singleton_buffer_point(Point::new(row, col), window, cx);
window, })
cx, .log_err();
); }
}) finder.update(cx, |_, cx| cx.emit(DismissEvent)).ok()?;
.log_err();
}
}
finder.update(cx, |_, cx| cx.emit(DismissEvent)).ok()?;
Some(()) Some(())
}) })
.detach(); .detach();
}
} }
} }

View file

@ -75,16 +75,16 @@ impl OpenPathDelegate {
.. ..
} => { } => {
let mut i = selected_match_index; let mut i = selected_match_index;
if let Some(user_input) = user_input { if let Some(user_input) = user_input
if !user_input.exists || !user_input.is_dir { && (!user_input.exists || !user_input.is_dir)
if i == 0 { {
return Some(CandidateInfo { if i == 0 {
path: user_input.file.clone(), return Some(CandidateInfo {
is_dir: false, path: user_input.file.clone(),
}); is_dir: false,
} else { });
i -= 1; } else {
} i -= 1;
} }
} }
let id = self.string_matches.get(i)?.candidate_id; let id = self.string_matches.get(i)?.candidate_id;

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