Detailed changes
@@ -343,7 +343,7 @@ impl ExtensionStore {
let index = this
.update(cx, |this, cx| this.rebuild_extension_index(cx))?
.await;
- this.update( cx, |this, cx| this.extensions_updated(index, cx))?
+ this.update(cx, |this, cx| this.extensions_updated(index, cx))?
.await;
index_changed = false;
}
@@ -758,29 +758,28 @@ impl ExtensionStore {
if let Some(content_length) = content_length {
let actual_len = tar_gz_bytes.len();
if content_length != actual_len {
- bail!("downloaded extension size {actual_len} does not match content length {content_length}");
+ bail!(concat!(
+ "downloaded extension size {actual_len} ",
+ "does not match content length {content_length}"
+ ));
}
}
let decompressed_bytes = GzipDecoder::new(BufReader::new(tar_gz_bytes.as_slice()));
let archive = Archive::new(decompressed_bytes);
archive.unpack(extension_dir).await?;
- this.update( cx, |this, cx| {
- this.reload(Some(extension_id.clone()), cx)
- })?
- .await;
+ this.update(cx, |this, cx| this.reload(Some(extension_id.clone()), cx))?
+ .await;
if let ExtensionOperation::Install = operation {
- this.update( cx, |this, cx| {
+ this.update(cx, |this, cx| {
cx.emit(Event::ExtensionInstalled(extension_id.clone()));
if let Some(events) = ExtensionEvents::try_global(cx)
- && let Some(manifest) = this.extension_manifest_for_id(&extension_id) {
- events.update(cx, |this, cx| {
- this.emit(
- extension::Event::ExtensionInstalled(manifest.clone()),
- cx,
- )
- });
- }
+ && let Some(manifest) = this.extension_manifest_for_id(&extension_id)
+ {
+ events.update(cx, |this, cx| {
+ this.emit(extension::Event::ExtensionInstalled(manifest.clone()), cx)
+ });
+ }
})
.ok();
}
@@ -143,9 +143,11 @@ impl LanguageModelProvider for CopilotChatLanguageModelProvider {
};
let Some(copilot) = Copilot::global(cx) else {
- return Task::ready( Err(anyhow!(
- "Copilot must be enabled for Copilot Chat to work. Please enable Copilot and try again."
- ).into()));
+ return Task::ready(Err(anyhow!(concat!(
+ "Copilot must be enabled for Copilot Chat to work. ",
+ "Please enable Copilot and try again."
+ ))
+ .into()));
};
let err = match copilot.read(cx).status() {
@@ -44,7 +44,11 @@ mod tests {
let expect_indents_to =
|buffer: &mut Buffer, cx: &mut Context<Buffer>, input: &str, expected: &str| {
- buffer.edit( [(0..buffer.len(), input)], Some(AutoindentMode::EachLine), cx, );
+ buffer.edit(
+ [(0..buffer.len(), input)],
+ Some(AutoindentMode::EachLine),
+ cx,
+ );
assert_eq!(buffer.text(), expected);
};
@@ -1653,21 +1653,24 @@ impl ProjectPanel {
match new_entry {
Err(e) => {
- project_panel.update_in( cx, |project_panel, window, cx| {
- project_panel.marked_entries.clear();
- project_panel.update_visible_entries(None, false, false, window, cx);
- }).ok();
+ project_panel
+ .update_in(cx, |project_panel, window, cx| {
+ project_panel.marked_entries.clear();
+ project_panel.update_visible_entries(None, false, false, window, cx);
+ })
+ .ok();
Err(e)?;
}
Ok(CreatedEntry::Included(new_entry)) => {
- project_panel.update_in( cx, |project_panel, window, cx| {
+ project_panel.update_in(cx, |project_panel, window, cx| {
if let Some(selection) = &mut project_panel.state.selection
- && selection.entry_id == edited_entry_id {
- selection.worktree_id = worktree_id;
- selection.entry_id = new_entry.id;
- project_panel.marked_entries.clear();
- project_panel.expand_to_selection(cx);
- }
+ && selection.entry_id == edited_entry_id
+ {
+ selection.worktree_id = worktree_id;
+ selection.entry_id = new_entry.id;
+ project_panel.marked_entries.clear();
+ project_panel.expand_to_selection(cx);
+ }
project_panel.update_visible_entries(None, false, false, window, cx);
if is_new_entry && !is_dir {
let settings = ProjectPanelSettings::get_global(cx);
@@ -1688,7 +1691,14 @@ impl ProjectPanel {
project_panel.project.update(cx, |_, cx| {
cx.emit(project::Event::Toast {
notification_id: "excluded-directory".into(),
- message: format!("Created an excluded directory at {abs_path:?}.\nAlter `file_scan_exclusions` in the settings to show it in the panel")
+ message: format!(
+ concat!(
+ "Created an excluded directory at {:?}.\n",
+ "Alter `file_scan_exclusions` in the settings ",
+ "to show it in the panel"
+ ),
+ abs_path
+ ),
})
});
None
@@ -1696,7 +1706,15 @@ impl ProjectPanel {
project_panel
.workspace
.update(cx, |workspace, cx| {
- workspace.open_abs_path(abs_path, OpenOptions { visible: Some(OpenVisible::All), ..Default::default() }, window, cx)
+ workspace.open_abs_path(
+ abs_path,
+ OpenOptions {
+ visible: Some(OpenVisible::All),
+ ..Default::default()
+ },
+ window,
+ cx,
+ )
})
.ok()
}
@@ -3600,32 +3618,44 @@ impl ProjectPanel {
cx.spawn_in(window, async move |this, cx| {
async move {
for (filename, original_path) in &paths_to_replace {
- let answer = cx.update(|window, cx| {
- window
- .prompt(
+ let prompt_message = format!(
+ concat!(
+ "A file or folder with name {} ",
+ "already exists in the destination folder. ",
+ "Do you want to replace it?"
+ ),
+ filename
+ );
+ let answer = cx
+ .update(|window, cx| {
+ window.prompt(
PromptLevel::Info,
- format!("A file or folder with name {filename} already exists in the destination folder. Do you want to replace it?").as_str(),
+ &prompt_message,
None,
&["Replace", "Cancel"],
cx,
)
- })?.await?;
+ })?
+ .await?;
if answer == 1
- && let Some(item_idx) = paths.iter().position(|p| p == original_path) {
- paths.remove(item_idx);
- }
+ && let Some(item_idx) = paths.iter().position(|p| p == original_path)
+ {
+ paths.remove(item_idx);
+ }
}
if paths.is_empty() {
return Ok(());
}
- let task = worktree.update( cx, |worktree, cx| {
+ let task = worktree.update(cx, |worktree, cx| {
worktree.copy_external_entries(target_directory, paths, fs, cx)
})?;
- let opened_entries = task.await.with_context(|| "failed to copy external paths")?;
+ let opened_entries = task
+ .await
+ .with_context(|| "failed to copy external paths")?;
this.update(cx, |this, cx| {
if open_file_after_drop && !opened_entries.is_empty() {
let settings = ProjectPanelSettings::get_global(cx);
@@ -3635,7 +3665,8 @@ impl ProjectPanel {
}
})
}
- .log_err().await
+ .log_err()
+ .await
})
.detach();
}
@@ -7306,14 +7306,9 @@ pub fn join_channel(
) -> Task<Result<()>> {
let active_call = ActiveCall::global(cx);
cx.spawn(async move |cx| {
- let result = join_channel_internal(
- channel_id,
- &app_state,
- requesting_window,
- &active_call,
- cx,
- )
- .await;
+ let result =
+ join_channel_internal(channel_id, &app_state, requesting_window, &active_call, cx)
+ .await;
// join channel succeeded, and opened a window
if matches!(result, Ok(true)) {
@@ -7321,8 +7316,7 @@ pub fn join_channel(
}
// find an existing workspace to focus and show call controls
- let mut active_window =
- requesting_window.or_else(|| activate_any_workspace_window( cx));
+ let mut active_window = requesting_window.or_else(|| activate_any_workspace_window(cx));
if active_window.is_none() {
// no open workspaces, make one to show the error in (blergh)
let (window_handle, _) = cx
@@ -7334,7 +7328,8 @@ pub fn join_channel(
if result.is_ok() {
cx.update(|cx| {
cx.dispatch_action(&OpenChannelNotes);
- }).log_err();
+ })
+ .log_err();
}
active_window = Some(window_handle);
@@ -7346,19 +7341,25 @@ pub fn join_channel(
active_window
.update(cx, |_, window, cx| {
let detail: SharedString = match err.error_code() {
- ErrorCode::SignedOut => {
- "Please sign in to continue.".into()
- }
- ErrorCode::UpgradeRequired => {
- "Your are running an unsupported version of Zed. Please update to continue.".into()
- }
- ErrorCode::NoSuchChannel => {
- "No matching channel was found. Please check the link and try again.".into()
- }
- ErrorCode::Forbidden => {
- "This channel is private, and you do not have access. Please ask someone to add you and try again.".into()
+ ErrorCode::SignedOut => "Please sign in to continue.".into(),
+ ErrorCode::UpgradeRequired => concat!(
+ "Your are running an unsupported version of Zed. ",
+ "Please update to continue."
+ )
+ .into(),
+ ErrorCode::NoSuchChannel => concat!(
+ "No matching channel was found. ",
+ "Please check the link and try again."
+ )
+ .into(),
+ ErrorCode::Forbidden => concat!(
+ "This channel is private, and you do not have access. ",
+ "Please ask someone to add you and try again."
+ )
+ .into(),
+ ErrorCode::Disconnected => {
+ "Please check your internet connection and try again.".into()
}
- ErrorCode::Disconnected => "Please check your internet connection and try again.".into(),
_ => format!("{}\n\nPlease try again.", err).into(),
};
window.prompt(
@@ -7366,7 +7367,8 @@ pub fn join_channel(
"Failed to join channel",
Some(&detail),
&["Ok"],
- cx)
+ cx,
+ )
})?
.await
.ok();
@@ -1918,53 +1918,67 @@ fn open_telemetry_log_file(
window: &mut Window,
cx: &mut Context<Workspace>,
) {
- workspace.with_local_workspace(window, cx, move |workspace, window, cx| {
- let app_state = workspace.app_state().clone();
- cx.spawn_in(window, async move |workspace, cx| {
- async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
- let path = client::telemetry::Telemetry::log_file_path();
- app_state.fs.load(&path).await.log_err()
- }
+ const HEADER: &str = concat!(
+ "// Zed collects anonymous usage data to help us understand how people are using the app.\n",
+ "// Telemetry can be disabled via the `settings.json` file.\n",
+ "// Here is the data that has been reported for the current session:\n",
+ );
+ workspace
+ .with_local_workspace(window, cx, move |workspace, window, cx| {
+ let app_state = workspace.app_state().clone();
+ cx.spawn_in(window, async move |workspace, cx| {
+ async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
+ let path = client::telemetry::Telemetry::log_file_path();
+ app_state.fs.load(&path).await.log_err()
+ }
- let log = fetch_log_string(&app_state).await.unwrap_or_else(|| "// No data has been collected yet".to_string());
+ let log = fetch_log_string(&app_state)
+ .await
+ .unwrap_or_else(|| "// No data has been collected yet".to_string());
- const MAX_TELEMETRY_LOG_LEN: usize = 5 * 1024 * 1024;
- let mut start_offset = log.len().saturating_sub(MAX_TELEMETRY_LOG_LEN);
- if let Some(newline_offset) = log[start_offset..].find('\n') {
- start_offset += newline_offset + 1;
- }
- let log_suffix = &log[start_offset..];
- let header = concat!(
- "// Zed collects anonymous usage data to help us understand how people are using the app.\n",
- "// Telemetry can be disabled via the `settings.json` file.\n",
- "// Here is the data that has been reported for the current session:\n",
- );
- let content = format!("{}\n{}", header, log_suffix);
- let json = app_state.languages.language_for_name("JSON").await.log_err();
-
- workspace.update_in( cx, |workspace, window, cx| {
- let project = workspace.project().clone();
- let buffer = project.update(cx, |project, cx| project.create_local_buffer(&content, json,false, cx));
- let buffer = cx.new(|cx| {
- MultiBuffer::singleton(buffer, cx).with_title("Telemetry Log".into())
- });
- workspace.add_item_to_active_pane(
- Box::new(cx.new(|cx| {
- let mut editor = Editor::for_multibuffer(buffer, Some(project), window, cx);
- editor.set_read_only(true);
- editor.set_breadcrumb_header("Telemetry Log".into());
- editor
- })),
- None,
- true,
- window, cx,
- );
- }).log_err()?;
+ const MAX_TELEMETRY_LOG_LEN: usize = 5 * 1024 * 1024;
+ let mut start_offset = log.len().saturating_sub(MAX_TELEMETRY_LOG_LEN);
+ if let Some(newline_offset) = log[start_offset..].find('\n') {
+ start_offset += newline_offset + 1;
+ }
+ let log_suffix = &log[start_offset..];
+ let content = format!("{}\n{}", HEADER, log_suffix);
+ let json = app_state
+ .languages
+ .language_for_name("JSON")
+ .await
+ .log_err();
+
+ workspace
+ .update_in(cx, |workspace, window, cx| {
+ let project = workspace.project().clone();
+ let buffer = project.update(cx, |project, cx| {
+ project.create_local_buffer(&content, json, false, cx)
+ });
+ let buffer = cx.new(|cx| {
+ MultiBuffer::singleton(buffer, cx).with_title("Telemetry Log".into())
+ });
+ workspace.add_item_to_active_pane(
+ Box::new(cx.new(|cx| {
+ let mut editor =
+ Editor::for_multibuffer(buffer, Some(project), window, cx);
+ editor.set_read_only(true);
+ editor.set_breadcrumb_header("Telemetry Log".into());
+ editor
+ })),
+ None,
+ true,
+ window,
+ cx,
+ );
+ })
+ .log_err()?;
- Some(())
+ Some(())
+ })
+ .detach();
})
.detach();
- }).detach();
}
fn open_bundled_file(
@@ -410,10 +410,15 @@ impl RateCompletionModal {
.overflow_hidden()
.relative()
.child(self.render_view_nav(cx))
- .when_some(match self.current_view {
- RateCompletionView::SuggestedEdits => self.render_suggested_edits(cx),
- RateCompletionView::RawInput => self.render_raw_input(cx),
- }, |this, element| this.child(element))
+ .when_some(
+ match self.current_view {
+ RateCompletionView::SuggestedEdits => {
+ self.render_suggested_edits(cx)
+ }
+ RateCompletionView::RawInput => self.render_raw_input(cx),
+ },
+ |this, element| this.child(element),
+ ),
)
.when(!rated, |this| {
this.child(
@@ -425,19 +430,18 @@ impl RateCompletionModal {
.child(
Icon::new(IconName::Info)
.size(IconSize::XSmall)
- .color(Color::Muted)
+ .color(Color::Muted),
)
.child(
- div()
- .w_full()
- .pr_2()
- .flex_wrap()
- .child(
- Label::new("Explain why this completion is good or bad. If it's negative, describe what you expected instead.")
- .size(LabelSize::Small)
- .color(Color::Muted)
- )
- )
+ div().w_full().pr_2().flex_wrap().child(
+ Label::new(concat!(
+ "Explain why this completion is good or bad. ",
+ "If it's negative, describe what you expected instead."
+ ))
+ .size(LabelSize::Small)
+ .color(Color::Muted),
+ ),
+ ),
)
})
.when(!rated, |this| {
@@ -446,7 +450,7 @@ impl RateCompletionModal {
.h_40()
.pt_1()
.bg(bg_color)
- .child(active_completion.feedback_editor.clone())
+ .child(active_completion.feedback_editor.clone()),
)
})
.child(
@@ -491,18 +495,21 @@ impl RateCompletionModal {
.icon_position(IconPosition::Start)
.disabled(rated || feedback_empty)
.when(feedback_empty, |this| {
- this.tooltip(Tooltip::text("Explain what's bad about it before reporting it"))
+ this.tooltip(Tooltip::text(
+ "Explain what's bad about it before reporting it",
+ ))
})
.key_binding(KeyBinding::for_action_in(
&ThumbsDownActiveCompletion,
focus_handle,
- cx
+ cx,
))
.on_click(cx.listener(move |this, _, window, cx| {
if this.active_completion.is_some() {
this.thumbs_down_active(
&ThumbsDownActiveCompletion,
- window, cx,
+ window,
+ cx,
);
}
})),
@@ -516,11 +523,15 @@ impl RateCompletionModal {
.key_binding(KeyBinding::for_action_in(
&ThumbsUpActiveCompletion,
focus_handle,
- cx
+ cx,
))
.on_click(cx.listener(move |this, _, window, cx| {
if this.active_completion.is_some() {
- this.thumbs_up_active(&ThumbsUpActiveCompletion, window, cx);
+ this.thumbs_up_active(
+ &ThumbsUpActiveCompletion,
+ window,
+ cx,
+ );
}
})),
),
@@ -528,6 +539,80 @@ impl RateCompletionModal {
),
)
}
+
+ fn render_shown_completions(&self, cx: &Context<Self>) -> impl Iterator<Item = ListItem> {
+ self.zeta
+ .read(cx)
+ .shown_completions()
+ .cloned()
+ .enumerate()
+ .map(|(index, completion)| {
+ let selected = self
+ .active_completion
+ .as_ref()
+ .is_some_and(|selected| selected.completion.id == completion.id);
+ let rated = self.zeta.read(cx).is_completion_rated(completion.id);
+
+ let (icon_name, icon_color, tooltip_text) =
+ match (rated, completion.edits.is_empty()) {
+ (true, _) => (IconName::Check, Color::Success, "Rated Completion"),
+ (false, true) => (IconName::File, Color::Muted, "No Edits Produced"),
+ (false, false) => (IconName::FileDiff, Color::Accent, "Edits Available"),
+ };
+
+ let file_name = completion
+ .path
+ .file_name()
+ .map(|f| f.to_string_lossy().into_owned())
+ .unwrap_or("untitled".to_string());
+ let file_path = completion
+ .path
+ .parent()
+ .map(|p| p.to_string_lossy().into_owned());
+
+ ListItem::new(completion.id)
+ .inset(true)
+ .spacing(ListItemSpacing::Sparse)
+ .focused(index == self.selected_index)
+ .toggle_state(selected)
+ .child(
+ h_flex()
+ .id("completion-content")
+ .gap_3()
+ .child(Icon::new(icon_name).color(icon_color).size(IconSize::Small))
+ .child(
+ v_flex()
+ .child(
+ h_flex()
+ .gap_1()
+ .child(Label::new(file_name).size(LabelSize::Small))
+ .when_some(file_path, |this, p| {
+ this.child(
+ Label::new(p)
+ .size(LabelSize::Small)
+ .color(Color::Muted),
+ )
+ }),
+ )
+ .child(
+ Label::new(format!(
+ "{} ago, {:.2?}",
+ format_time_ago(
+ completion.response_received_at.elapsed()
+ ),
+ completion.latency()
+ ))
+ .color(Color::Muted)
+ .size(LabelSize::XSmall),
+ ),
+ ),
+ )
+ .tooltip(Tooltip::text(tooltip_text))
+ .on_click(cx.listener(move |this, _, window, cx| {
+ this.select_completion(Some(completion.clone()), true, window, cx);
+ }))
+ })
+ }
}
impl Render for RateCompletionModal {
@@ -571,15 +656,12 @@ impl Render for RateCompletionModal {
.justify_between()
.border_b_1()
.border_color(border_color)
- .child(
- Icon::new(IconName::ZedPredict)
- .size(IconSize::Small)
- )
+ .child(Icon::new(IconName::ZedPredict).size(IconSize::Small))
.child(
Label::new("From most recent to oldest")
.color(Color::Muted)
.size(LabelSize::Small),
- )
+ ),
)
.child(
div()
@@ -593,66 +675,20 @@ impl Render for RateCompletionModal {
div()
.p_2()
.child(
- Label::new("No completions yet. Use the editor to generate some, and make sure to rate them!")
- .color(Color::Muted),
+ Label::new(concat!(
+ "No completions yet. ",
+ "Use the editor to generate some, ",
+ "and make sure to rate them!"
+ ))
+ .color(Color::Muted),
)
.into_any_element(),
)
- .children(self.zeta.read(cx).shown_completions().cloned().enumerate().map(
- |(index, completion)| {
- let selected =
- self.active_completion.as_ref().is_some_and(|selected| {
- selected.completion.id == completion.id
- });
- let rated =
- self.zeta.read(cx).is_completion_rated(completion.id);
-
- let (icon_name, icon_color, tooltip_text) = match (rated, completion.edits.is_empty()) {
- (true, _) => (IconName::Check, Color::Success, "Rated Completion"),
- (false, true) => (IconName::File, Color::Muted, "No Edits Produced"),
- (false, false) => (IconName::FileDiff, Color::Accent, "Edits Available"),
- };
-
- let file_name = completion.path.file_name().map(|f| f.to_string_lossy().into_owned()).unwrap_or("untitled".to_string());
- let file_path = completion.path.parent().map(|p| p.to_string_lossy().into_owned());
-
- ListItem::new(completion.id)
- .inset(true)
- .spacing(ListItemSpacing::Sparse)
- .focused(index == self.selected_index)
- .toggle_state(selected)
- .child(
- h_flex()
- .id("completion-content")
- .gap_3()
- .child(
- Icon::new(icon_name)
- .color(icon_color)
- .size(IconSize::Small)
- )
- .child(
- v_flex()
- .child(
- h_flex().gap_1()
- .child(Label::new(file_name).size(LabelSize::Small))
- .when_some(file_path, |this, p| this.child(Label::new(p).size(LabelSize::Small).color(Color::Muted)))
- )
- .child(Label::new(format!("{} ago, {:.2?}", format_time_ago(completion.response_received_at.elapsed()), completion.latency()))
- .color(Color::Muted)
- .size(LabelSize::XSmall)
- )
- )
- )
- .tooltip(Tooltip::text(tooltip_text))
- .on_click(cx.listener(move |this, _, window, cx| {
- this.select_completion(Some(completion.clone()), true, window, cx);
- }))
- },
- )),
- )
+ .children(self.render_shown_completions(cx)),
+ ),
),
)
- .children(self.render_active_completion( cx))
+ .children(self.render_active_completion(cx))
.on_mouse_down_out(cx.listener(|_, _, _, cx| cx.emit(DismissEvent)))
}
}
@@ -76,21 +76,26 @@ pub(crate) fn run_tests() -> Workflow {
jobs.push(should_run_tests.guard(check_postgres_and_protobuf_migrations())); // could be more specific here?
named::workflow()
- .add_event(Event::default()
- .push(
- Push::default()
- .add_branch("main")
- .add_branch("v[0-9]+.[0-9]+.x")
- )
- .pull_request(PullRequest::default().add_branch("**"))
+ .add_event(
+ Event::default()
+ .push(
+ Push::default()
+ .add_branch("main")
+ .add_branch("v[0-9]+.[0-9]+.x"),
+ )
+ .pull_request(PullRequest::default().add_branch("**")),
)
- .concurrency(Concurrency::default()
- .group("${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}")
- .cancel_in_progress(true)
+ .concurrency(
+ Concurrency::default()
+ .group(concat!(
+ "${{ github.workflow }}-${{ github.ref_name }}-",
+ "${{ github.ref_name == 'main' && github.sha || 'anysha' }}"
+ ))
+ .cancel_in_progress(true),
)
- .add_env(( "CARGO_TERM_COLOR", "always" ))
- .add_env(( "RUST_BACKTRACE", 1 ))
- .add_env(( "CARGO_INCREMENTAL", 0 ))
+ .add_env(("CARGO_TERM_COLOR", "always"))
+ .add_env(("RUST_BACKTRACE", 1))
+ .add_env(("CARGO_INCREMENTAL", 0))
.map(|mut workflow| {
for job in jobs {
workflow = workflow.add_job(job.name, job.job)