Compare commits

...

12 Commits

Author SHA1 Message Date
Conrad Irwin
bc6e7dbd1b zed 0.131.4 2024-04-12 14:27:05 -06:00
gcp-cherry-pick-bot[bot]
18f0bc4c84 Fix emojis when rendering with the system ui font (cherry-pick #10491) (#10493)
Cherry-picked Fix emojis when rendering with the system ui font (#10491)

Release Notes:

- N/A

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-04-12 14:20:56 -06:00
gcp-cherry-pick-bot[bot]
4ef4748681 Use buffer font for search (cherry-pick #10455) (#10494)
Cherry-picked Use buffer font for search (#10455)

It's wierd to type code/regex in the UI font

Release Notes:

- Continue to use buffer font for search

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-04-12 14:20:46 -06:00
gcp-cherry-pick-bot[bot]
30824089b2 Use buffer font when rendering editor breadcrumbs and diagnostics (cherry-pick #10488) (#10495)
Cherry-picked Use buffer font when rendering editor breadcrumbs and
diagnostics (#10488)

Before:

<img width="592" alt="Screenshot 2024-04-12 at 12 00 00 PM"

src="https://github.com/zed-industries/zed/assets/2280405/3251743e-4f2c-4ca3-9bc5-88f37660f7b9">

After:

<img width="673" alt="Screenshot 2024-04-12 at 12 11 37 PM"

src="https://github.com/zed-industries/zed/assets/2280405/6a8ac597-261a-45d9-bf2a-a673b6f26b0e">


Release Notes:

- N/A

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
2024-04-12 14:20:36 -06:00
Kyle Kelley
5df5a400e9 zed 0.131.3 2024-04-11 13:54:35 -07:00
gcp-cherry-pick-bot[bot]
ca62f6e231 Do not show image viewer for SVGs (cherry-pick #10435) (#10447)
Cherry-picked Do not show image viewer for SVGs (#10435)

Absent some ability to toggle between viewing and editing a file, I
think it would be best to get a fix out quick for people to edit SVGs as
text files.

Release Notes:

- Fixed editing of SVG images by disabling it from the image viewer
([#10403](https://github.com/zed-industries/zed/issues/10403)).

Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
2024-04-11 13:50:38 -07:00
Marshall Bowers
b01c07b17d zed 0.131.2 2024-04-11 14:54:50 -04:00
gcp-cherry-pick-bot[bot]
c35c957e7a Validate content-length of downloaded extension tar gz files (cherry-pick #10430) (#10440)
Cherry-picked Validate content-length of downloaded extension tar gz
files (#10430)

Release Notes:

- Fixed a bug where extension installation would appear to succeed even
if the download did not complete due to network interruptions
([#10330](https://github.com/zed-industries/zed/issues/10330)).

Co-authored-by: Marshall <marshall@zed.dev>

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Marshall <marshall@zed.dev>
2024-04-11 14:53:36 -04:00
Kirill Bulatov
0137e7e1e0 zed 0.131.1 2024-04-11 01:12:45 +03:00
Kirill Bulatov
25b8e46b98 Use proper Workspace references when querying for tasks by name (#10383)
Closes https://github.com/zed-industries/zed/issues/10380

Release Notes:

- Fixed Zed panicking when running tasks via a keybinding
([10380](https://github.com/zed-industries/zed/issues/10380))
2024-04-11 00:43:26 +03:00
gcp-cherry-pick-bot[bot]
04e6d5d553 Fix panic when loading malformed Wasm files (cherry-pick #10370) (#10371)
Cherry-picked Fix panic when loading malformed Wasm files (#10370)

This PR fixes a potential panic that could occur when loading malformed
Wasm files.

We now use the `parse_wasm_extension_version` function that was
previously used just to extract the Zed extension API version from the
Wasm bytes as a pre-validation step. By parsing the entirety of the Wasm
file here instead of returning as soon as we find the version, the
invalid Wasm bytes are now surfaced as an `Err` instead of a panic.

We were able to replicate the panic using the following test:

```rs
#[gpui::test]
async fn test_bad_wasm(cx: &mut TestAppContext) {
    init_test(cx);

    let wasm_host = cx.update(|cx| {
        WasmHost::new(
            FakeFs::new(cx.background_executor().clone()),
            FakeHttpClient::with_200_response(),
            FakeNodeRuntime::new(),
            Arc::new(LanguageRegistry::test(cx.background_executor().clone())),
            PathBuf::from("/the/work/dir".to_string()),
            cx,
        )
    });

    let mut wasm_bytes = std::fs::read("/Users/maxdeviant/Library/Application Support/Zed/extensions/installed/dart/extension.wasm").unwrap();

    // This is the error message we were seeing in the stack trace:
    // range end index 267037 out of range for slice of length 253952

    dbg!(&wasm_bytes.len());

    // Truncate the bytes to the same point:
    wasm_bytes.truncate(253952);

    std::fs::write("/tmp/bad-extension.wasm", wasm_bytes.clone()).unwrap();

    let manifest = Arc::new(ExtensionManifest {
        id: "the-extension".into(),
        name: "The Extension".into(),
        version: "0.0.1".into(),
        schema_version: SchemaVersion(1),
        description: Default::default(),
        repository: Default::default(),
        authors: Default::default(),
        lib: LibManifestEntry {
            kind: None,
            version: None,
        },
        themes: Default::default(),
        languages: Default::default(),
        grammars: Default::default(),
        language_servers: Default::default(),
    });

    // 💥
    let result = wasm_host
        .load_extension(wasm_bytes, manifest, cx.executor())
        .await;
    dbg!(result.map(|_| ()));
```



Release Notes:

- Fixed a crash that could occur when loading malformed Wasm extensions
([#10352](https://github.com/zed-industries/zed/issues/10352)).

---------

Co-authored-by: Max <max@zed.dev>

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
Co-authored-by: Max <max@zed.dev>
2024-04-10 14:19:46 -04:00
Joseph T. Lyons
547d02227d v0.131.x preview 2024-04-10 11:44:54 -04:00
17 changed files with 100 additions and 33 deletions

3
Cargo.lock generated
View File

@@ -3588,6 +3588,7 @@ dependencies = [
"fs",
"futures 0.3.28",
"gpui",
"isahc",
"language",
"log",
"lsp",
@@ -12514,7 +12515,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.131.0"
version = "0.131.4"
dependencies = [
"activity_indicator",
"anyhow",

View File

@@ -52,12 +52,19 @@ impl Render for Breadcrumbs {
Some(BreadcrumbText {
text: "".into(),
highlights: None,
font: None,
}),
);
}
let highlighted_segments = segments.into_iter().map(|segment| {
let mut text_style = cx.text_style();
if let Some(font) = segment.font {
text_style.font_family = font.family;
text_style.font_features = font.features;
text_style.font_style = font.style;
text_style.font_weight = font.weight;
}
text_style.color = Color::Muted.color(cx);
StyledText::new(segment.text.replace('\n', ""))

View File

@@ -10568,6 +10568,11 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren
let mut text_style = cx.text_style().clone();
text_style.color = diagnostic_style(diagnostic.severity, true, cx.theme().status());
let theme_settings = ThemeSettings::get_global(cx);
text_style.font_family = theme_settings.buffer_font.family.clone();
text_style.font_style = theme_settings.buffer_font.style;
text_style.font_features = theme_settings.buffer_font.features;
text_style.font_weight = theme_settings.buffer_font.weight;
let multi_line_diagnostic = diagnostic.message.contains('\n');

View File

@@ -30,7 +30,7 @@ use std::{
sync::Arc,
};
use text::{BufferId, Selection};
use theme::Theme;
use theme::{Theme, ThemeSettings};
use ui::{h_flex, prelude::*, Label};
use util::{paths::PathExt, ResultExt, TryFutureExt};
use workspace::item::{BreadcrumbText, FollowEvent, FollowableItemHandle};
@@ -824,13 +824,18 @@ impl Item for Editor {
.map(|path| path.to_string_lossy().to_string())
.unwrap_or_else(|| "untitled".to_string());
let settings = ThemeSettings::get_global(cx);
let mut breadcrumbs = vec![BreadcrumbText {
text: filename,
highlights: None,
font: Some(settings.buffer_font.clone()),
}];
breadcrumbs.extend(symbols.into_iter().map(|symbol| BreadcrumbText {
text: symbol.text,
highlights: Some(symbol.highlight_ranges),
font: Some(settings.buffer_font.clone()),
}));
Some(breadcrumbs)
}

View File

@@ -23,6 +23,7 @@ collections.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
isahc.workspace = true
language.workspace = true
log.workspace = true
lsp.workspace = true

View File

@@ -606,7 +606,23 @@ impl ExtensionStore {
)
.await?;
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
let content_length = response
.headers()
.get(isahc::http::header::CONTENT_LENGTH)
.and_then(|value| value.to_str().ok()?.parse::<usize>().ok());
let mut body = BufReader::new(response.body_mut());
let mut tgz_bytes = Vec::new();
body.read_to_end(&mut tgz_bytes).await?;
if let Some(content_length) = content_length {
let actual_len = tgz_bytes.len();
if content_length != actual_len {
bail!("downloaded extension size {actual_len} does not match content length {content_length}");
}
}
let decompressed_bytes = GzipDecoder::new(BufReader::new(tgz_bytes.as_slice()));
// let decompressed_bytes = GzipDecoder::new(BufReader::new(tgz_bytes));
let archive = Archive::new(decompressed_bytes);
archive.unpack(extension_dir).await?;
this.update(&mut cx, |this, cx| {

View File

@@ -198,13 +198,15 @@ pub fn parse_wasm_extension_version(
extension_id: &str,
wasm_bytes: &[u8],
) -> Result<SemanticVersion> {
let mut version = None;
for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) {
if let wasmparser::Payload::CustomSection(s) = part? {
if let wasmparser::Payload::CustomSection(s) =
part.context("error parsing wasm extension")?
{
if s.name() == "zed:api-version" {
let version = parse_wasm_extension_version_custom_section(s.data());
if let Some(version) = version {
return Ok(version);
} else {
version = parse_wasm_extension_version_custom_section(s.data());
if version.is_none() {
bail!(
"extension {} has invalid zed:api-version section: {:?}",
extension_id,
@@ -214,7 +216,13 @@ pub fn parse_wasm_extension_version(
}
}
}
bail!("extension {} has no zed:api-version section", extension_id)
// The reason we wait until we're done parsing all of the Wasm bytes to return the version
// is to work around a panic that can happen inside of Wasmtime when the bytes are invalid.
//
// By parsing the entirety of the Wasm bytes before we return, we're able to detect this problem
// earlier as an `Err` rather than as a panic.
version.ok_or_else(|| anyhow!("extension {} has no zed:api-version section", extension_id))
}
fn parse_wasm_extension_version_custom_section(data: &[u8]) -> Option<SemanticVersion> {

View File

@@ -334,7 +334,7 @@ impl MacTextSystemState {
self.postscript_names_by_font_id
.get(&font_id)
.map_or(false, |postscript_name| {
postscript_name == "AppleColorEmoji"
postscript_name == "AppleColorEmoji" || postscript_name == ".AppleColorEmojiUI"
})
}

View File

@@ -37,7 +37,9 @@ impl project::Item for ImageItem {
.and_then(OsStr::to_str)
.unwrap_or_default();
if Img::extensions().contains(&ext) {
// Only open the item if it's a binary image (no SVGs, etc.)
// Since we do not have a way to toggle to an editor
if Img::extensions().contains(&ext) && !ext.contains("svg") {
Some(cx.spawn(|mut cx| async move {
let abs_path = project
.read_with(&cx, |project, cx| project.absolute_path(&path, cx))?

View File

@@ -113,8 +113,8 @@ impl BufferSearchBar {
} else {
color
},
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features,
font_family: settings.buffer_font.family.clone(),
font_features: settings.buffer_font.features,
font_size: rems(0.875).into(),
font_weight: FontWeight::NORMAL,
font_style: FontStyle::Normal,

View File

@@ -1421,8 +1421,8 @@ impl ProjectSearchBar {
} else {
cx.theme().colors().text
},
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features,
font_family: settings.buffer_font.family.clone(),
font_features: settings.buffer_font.features,
font_size: rems(0.875).into(),
font_weight: FontWeight::NORMAL,
font_style: FontStyle::Normal,

View File

@@ -2,7 +2,7 @@ use std::{path::PathBuf, sync::Arc};
use ::settings::Settings;
use editor::Editor;
use gpui::{AppContext, ViewContext, WeakView, WindowContext};
use gpui::{AppContext, ViewContext, WindowContext};
use language::{Language, Point};
use modal::{Spawn, TasksModal};
use project::{Location, WorktreeId};
@@ -60,17 +60,17 @@ fn spawn_task_or_modal(workspace: &mut Workspace, action: &Spawn, cx: &mut ViewC
fn spawn_task_with_name(name: String, cx: &mut ViewContext<Workspace>) {
cx.spawn(|workspace, mut cx| async move {
let did_spawn = workspace
.update(&mut cx, |this, cx| {
let (worktree, language) = active_item_selection_properties(&workspace, cx);
let tasks = this.project().update(cx, |project, cx| {
.update(&mut cx, |workspace, cx| {
let (worktree, language) = active_item_selection_properties(workspace, cx);
let tasks = workspace.project().update(cx, |project, cx| {
project.task_inventory().update(cx, |inventory, cx| {
inventory.list_tasks(language, worktree, false, cx)
})
});
let (_, target_task) = tasks.into_iter().find(|(_, task)| task.name() == name)?;
let cwd = task_cwd(this, cx).log_err().flatten();
let task_context = task_context(this, cwd, cx);
schedule_task(this, &target_task, task_context, false, cx);
let cwd = task_cwd(workspace, cx).log_err().flatten();
let task_context = task_context(workspace, cwd, cx);
schedule_task(workspace, &target_task, task_context, false, cx);
Some(())
})
.ok()
@@ -88,13 +88,10 @@ fn spawn_task_with_name(name: String, cx: &mut ViewContext<Workspace>) {
}
fn active_item_selection_properties(
workspace: &WeakView<Workspace>,
workspace: &Workspace,
cx: &mut WindowContext,
) -> (Option<WorktreeId>, Option<Arc<Language>>) {
let active_item = workspace
.update(cx, |workspace, cx| workspace.active_item(cx))
.ok()
.flatten();
let active_item = workspace.active_item(cx);
let worktree_id = active_item
.as_ref()
.and_then(|item| item.project_path(cx))

View File

@@ -195,8 +195,13 @@ impl PickerDelegate for TasksModalDelegate {
let Some(candidates) = picker
.update(&mut cx, |picker, cx| {
let candidates = picker.delegate.candidates.get_or_insert_with(|| {
let (worktree, language) =
active_item_selection_properties(&picker.delegate.workspace, cx);
let Ok((worktree, language)) =
picker.delegate.workspace.update(cx, |workspace, cx| {
active_item_selection_properties(workspace, cx)
})
else {
return Vec::new();
};
picker.delegate.inventory.update(cx, |inventory, cx| {
inventory.list_tasks(language, worktree, true, cx)
})
@@ -376,6 +381,8 @@ mod tests {
use project::{FakeFs, Project};
use serde_json::json;
use crate::modal::Spawn;
use super::*;
#[gpui::test]
@@ -514,13 +521,29 @@ mod tests {
vec!["echo 4", "another one", "example task", "echo 40"],
"Last recently used one show task should be listed last, as it is a fire-and-forget task"
);
cx.dispatch_action(Spawn {
task_name: Some("example task".to_string()),
});
let tasks_picker = workspace.update(cx, |workspace, cx| {
workspace
.active_modal::<TasksModal>(cx)
.unwrap()
.read(cx)
.picker
.clone()
});
assert_eq!(
task_names(&tasks_picker, cx),
vec!["echo 4", "another one", "example task", "echo 40"],
);
}
fn open_spawn_tasks(
workspace: &View<Workspace>,
cx: &mut VisualTestContext,
) -> View<Picker<TasksModalDelegate>> {
cx.dispatch_action(crate::modal::Spawn::default());
cx.dispatch_action(Spawn::default());
workspace.update(cx, |workspace, cx| {
workspace
.active_modal::<TasksModal>(cx)

View File

@@ -866,6 +866,7 @@ impl Item for TerminalView {
Some(vec![BreadcrumbText {
text: self.terminal().read(cx).breadcrumb_text.clone(),
highlights: None,
font: None,
}])
}

View File

@@ -14,7 +14,7 @@ use client::{
use futures::{channel::mpsc, StreamExt};
use gpui::{
AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
HighlightStyle, Model, Pixels, Point, SharedString, Task, View, ViewContext, WeakView,
Font, HighlightStyle, Model, Pixels, Point, SharedString, Task, View, ViewContext, WeakView,
WindowContext,
};
use project::{Project, ProjectEntryId, ProjectPath};
@@ -93,6 +93,7 @@ pub enum ItemEvent {
pub struct BreadcrumbText {
pub text: String,
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
pub font: Option<Font>,
}
pub trait Item: FocusableView + EventEmitter<Self::Event> {

View File

@@ -2,7 +2,7 @@
description = "The fast, collaborative code editor."
edition = "2021"
name = "zed"
version = "0.131.0"
version = "0.131.4"
publish = false
license = "GPL-3.0-or-later"
authors = ["Zed Team <hi@zed.dev>"]

View File

@@ -1 +1 @@
dev
preview