Compare commits

...

12 Commits

Author SHA1 Message Date
Max Brunsfeld
7380ab8a1a Remove old extension dir when upgrading (#9800)
Fixes #9799

Release Notes:

- Fixed a bug where upgrading an extension did not work correctly if the
extension had switched from using an old extension schema with
`extension.json` to the new schema with `extension.toml`.
2024-03-27 12:02:44 -04:00
Joseph T. Lyons
f3e557d106 v0.128.x stable 2024-03-27 10:52:55 -04:00
Kirill Bulatov
99775968c1 Make UniformList non-occluding.
Move the `occlude` in the places where they are needed.

Co-authored-by: Antonio Scandurra <antonio@zed.dev>
2024-03-26 13:59:50 +02:00
Thorsten Ball
3e2590842d zed 0.128.3 2024-03-26 06:14:57 +01:00
Thorsten Ball
9ed7822278 Update to vscode-eslint 2.4.4 & support flat config file extensions (#9708)
This upgrades to vscode-eslint 2.4.4 to support flat configs, in
multiple configuration files, ending in `.js`, `.cjs`, `.mjs`.

We changed the code to not use the GitHub release because we actually
don't need the artifacts of the release, we just need the source code,
which we compile anyway.

Fixes #7271.

Release Notes:

- Added support for ESLint flat config files.
([#7271](https://github.com/zed-industries/zed/issues/7271)).

Co-authored-by: Kristján Oddsson <koddsson@gmail.com>
2024-03-26 06:13:54 +01:00
Remco Smits
ff0164eeb6 Fix prettier-plugin-organize-imports plugin removes used imports (#9598)
So this pull request fixes an issue that was driven me crazy. The issue
was that when you use the `prettier-plugin-organize-imports` It would
remove some imports that should not be removed before they were used
inside the module itself.

You can reproduce it with the following `prettierrc.json` config and
source code. When you **save** the file, it would remove the `import
clsx from "clsx";` import from the file.

**Prettier config**
```json
{
  "semi": true,
  "tabWidth": 4,
  "trailingComma": "es5",
  "useTabs": true,
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-organize-imports"
  ]
}
```

**Source code**
```typescript
import clsx from "clsx";

export default function Home() {
  return (
      <main>
	      {clsx("asdjklasdjlkasd", "asdjlkasjdjlk")}
      </main>
  );
}
```

After a deep dive with @mrnugget, I was debugging deep down the prettier
plugin system and found the issue that was causing this issue. When I
was looking inside the
`node_modules/prettier-plugin-organize-imports/lib/organize.js`. I saw
the following code that looked strange to me because it falls back to
`file.ts` if `filepath` is not passed through inside the prettier config
options.

<img width="860" alt="Screenshot 2024-03-20 at 21 31 46"
src="https://github.com/zed-industries/zed/assets/62463826/47177fe5-e5a9-41d8-9f2f-0304b2c2159f">

So the issue was small, if you look at the following code, the `path`
key should be `filepath` inside the
`crates/prettier/src/prettier_server.js:205`
![Screenshot 2024-03-20 at 21 35
25](https://github.com/zed-industries/zed/assets/62463826/1eea0a88-c886-4632-9c69-9f3095126971)

Release Notes:

- Fixed prettier integration not using the correct filepath when
invoking prettier, which could lead to some prettier plugins failing to
format correctly.
([#9496](https://github.com/zed-industries/zed/issues/9496)).
2024-03-26 06:13:31 +01:00
gcp-cherry-pick-bot[bot]
42967551c7 chat panel: Fix tooltips not working for links (cherry-pick #9691) (#9699)
Cherry-picked chat panel: Fix tooltips not working for links (#9691)

Closes #9418 

Noticed a difference in the `cx.set_tooltip(...)` calls between `div`
and `InteractiveText`. `div` calls `cx.set_tooltip(...)` inside
`after_layout`, but `InteractiveText` was calling this inside `paint`. I
believe as #9012 was merged, we need to call `cx.set_tooltip` inside
`after_layout`, as inserting inside `paint` does not seem to be
supported anymore.

I moved the code for setting the tooltip to `after_layout` and hovering
over links inside the chat seems to bring up the tooltips again.

Before:

See https://github.com/zed-industries/zed/issues/9418#issue-2189398784

After:



![image](https://github.com/zed-industries/zed/assets/53836821/a623164c-1ce0-40d7-bc53-020f176fba4a)


Release Notes:

- Fixed tooltip not showing up when hovering over links inside the chat
panel ([#9418](https://github.com/zed-industries/zed/issues/9418))

Co-authored-by: Bennet Bo Fenner <53836821+bennetbo@users.noreply.github.com>
2024-03-22 14:49:18 +01:00
Antonio Scandurra
ddc2844949 zed 0.128.2 2024-03-22 09:17:06 +01:00
gcp-cherry-pick-bot[bot]
646b493b9d Hard code max token counts for supported models (cherry-pick #9675) (#9685)
Cherry-picked Hard code max token counts for supported models (#9675)

Co-authored-by: Nathan Sobo <nathan@zed.dev>
2024-03-22 09:00:19 +01:00
Conrad Irwin
8ca7b0dded zed 0.128.1 2024-03-20 21:02:32 -06:00
gcp-cherry-pick-bot[bot]
383473c94b Fix copilot modal (cherry-pick #9613) (#9615)
Cherry-picked Fix copilot modal (#9613)

Release Notes:

- Fixed copilot modal not responding
([#9596](https://github.com/zed-industries/zed/issues/9596)). (preview
only)

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-03-20 21:01:48 -06:00
Mikayla
77b71879fe v0.128.x preview 2024-03-20 09:16:16 -07:00
14 changed files with 89 additions and 105 deletions

2
Cargo.lock generated
View File

@@ -12541,7 +12541,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.128.0"
version = "0.128.3"
dependencies = [
"activity_indicator",
"anyhow",

View File

@@ -97,13 +97,8 @@ impl LanguageModel {
pub fn max_token_count(&self) -> usize {
match self {
LanguageModel::OpenAi(model) => tiktoken_rs::model::get_context_size(model.id()),
LanguageModel::ZedDotDev(model) => match model {
ZedDotDevModel::GptThreePointFiveTurbo
| ZedDotDevModel::GptFour
| ZedDotDevModel::GptFourTurbo => tiktoken_rs::model::get_context_size(model.id()),
ZedDotDevModel::Custom(_) => 30720, // TODO: Base this on the selected model.
},
LanguageModel::OpenAi(model) => model.max_token_count(),
LanguageModel::ZedDotDev(model) => model.max_token_count(),
}
}

View File

@@ -109,6 +109,15 @@ impl ZedDotDevModel {
Self::Custom(id) => id.as_str(),
}
}
pub fn max_token_count(&self) -> usize {
match self {
Self::GptThreePointFiveTurbo => 2048,
Self::GptFour => 4096,
Self::GptFourTurbo => 128000,
Self::Custom(_) => 4096, // TODO: Make this configurable
}
}
}
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema)]

View File

@@ -194,9 +194,8 @@ impl Render for CopilotCodeVerification {
.on_action(cx.listener(|_, _: &menu::Cancel, cx| {
cx.emit(DismissEvent);
}))
.capture_any_mouse_down(cx.listener(|this, _: &MouseDownEvent, cx| {
.on_any_mouse_down(cx.listener(|this, _: &MouseDownEvent, cx| {
cx.focus(&this.focus_handle);
cx.stop_propagation();
}))
.child(
svg()

View File

@@ -898,9 +898,7 @@ impl CompletionsMenu {
.max_w(px(640.))
.w(px(500.))
.overflow_y_scroll()
// Prevent a mouse down on documentation from being propagated to the editor,
// because that would move the cursor.
.on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation())
.occlude()
})
} else {
None
@@ -989,6 +987,7 @@ impl CompletionsMenu {
.collect()
},
)
.occlude()
.max_h(max_height)
.track_scroll(self.scroll_handle.clone())
.with_width_from_item(widest_completion_ix);
@@ -1212,6 +1211,7 @@ impl CodeActionsMenu {
.px_2()
.py_1()
.max_h(max_height)
.occlude()
.track_scroll(self.scroll_handle.clone())
.with_width_from_item(
self.actions

View File

@@ -424,8 +424,9 @@ impl ExtensionStore {
operation: ExtensionOperation,
cx: &mut ModelContext<Self>,
) {
let extensions_dir = self.extensions_dir();
let extension_dir = self.installed_dir.join(extension_id.as_ref());
let http_client = self.http_client.clone();
let fs = self.fs.clone();
match self.outstanding_operations.entry(extension_id.clone()) {
hash_map::Entry::Occupied(_) => return,
@@ -450,11 +451,19 @@ impl ExtensionStore {
.get(&url, Default::default(), true)
.await
.map_err(|err| anyhow!("error downloading extension: {}", err))?;
fs.remove_dir(
&extension_dir,
RemoveOptions {
recursive: true,
ignore_if_not_exists: true,
},
)
.await?;
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
let archive = Archive::new(decompressed_bytes);
archive
.unpack(extensions_dir.join(extension_id.as_ref()))
.await?;
archive.unpack(extension_dir).await?;
this.update(&mut cx, |this, cx| {
this.reload(Some(extension_id.clone()), cx)
})?
@@ -519,7 +528,7 @@ impl ExtensionStore {
}
pub fn uninstall_extension(&mut self, extension_id: Arc<str>, cx: &mut ModelContext<Self>) {
let extensions_dir = self.extensions_dir();
let extension_dir = self.installed_dir.join(extension_id.as_ref());
let fs = self.fs.clone();
match self.outstanding_operations.entry(extension_id.clone()) {
@@ -542,7 +551,7 @@ impl ExtensionStore {
});
fs.remove_dir(
&extensions_dir.join(extension_id.as_ref()),
&extension_dir,
RemoveOptions {
recursive: true,
ignore_if_not_exists: true,

View File

@@ -415,8 +415,26 @@ impl Element for InteractiveText {
state: &mut Self::BeforeLayout,
cx: &mut ElementContext,
) -> Hitbox {
self.text.after_layout(bounds, state, cx);
cx.insert_hitbox(bounds, false)
cx.with_element_state::<InteractiveTextState, _>(
Some(self.element_id.clone()),
|interactive_state, cx| {
let interactive_state = interactive_state
.map(|interactive_state| interactive_state.unwrap_or_default());
if let Some(interactive_state) = interactive_state.as_ref() {
if let Some(active_tooltip) = interactive_state.active_tooltip.borrow().as_ref()
{
if let Some(tooltip) = active_tooltip.tooltip.clone() {
cx.set_tooltip(tooltip);
}
}
}
self.text.after_layout(bounds, state, cx);
let hitbox = cx.insert_hitbox(bounds, false);
(hitbox, interactive_state)
},
)
}
fn paint(
@@ -557,16 +575,6 @@ impl Element for InteractiveText {
cx.on_mouse_event(move |_: &MouseDownEvent, _, _| {
active_tooltip.take();
});
if let Some(tooltip) = interactive_state
.active_tooltip
.clone()
.borrow()
.as_ref()
.and_then(|at| at.tooltip.clone())
{
cx.set_tooltip(tooltip);
}
}
self.text.paint(bounds, text_state, &mut (), cx);

View File

@@ -48,7 +48,6 @@ where
interactivity: Interactivity {
element_id: Some(id),
base_style: Box::new(base_style),
occlude_mouse: true,
#[cfg(debug_assertions)]
location: Some(*core::panic::Location::caller()),

View File

@@ -20,7 +20,7 @@ use std::{
use util::{
async_maybe,
fs::remove_matching,
github::{github_release_with_tag, GitHubLspBinaryVersion},
github::{build_tarball_url, GitHubLspBinaryVersion},
ResultExt,
};
@@ -227,9 +227,14 @@ pub struct EsLintLspAdapter {
}
impl EsLintLspAdapter {
const CURRENT_VERSION: &'static str = "release/2.4.4";
const SERVER_PATH: &'static str = "vscode-eslint/server/out/eslintServer.js";
const SERVER_NAME: &'static str = "eslint";
const FLAT_CONFIG_FILE_NAMES: &'static [&'static str] =
&["eslint.config.js", "eslint.config.mjs", "eslint.config.cjs"];
pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
EsLintLspAdapter { node }
}
@@ -266,6 +271,9 @@ impl LspAdapter for EsLintLspAdapter {
}
let node_path = eslint_user_settings.get("nodePath").unwrap_or(&Value::Null);
let use_flat_config = Self::FLAT_CONFIG_FILE_NAMES
.iter()
.any(|file| workspace_root.join(file).is_file());
json!({
"": {
@@ -282,7 +290,7 @@ impl LspAdapter for EsLintLspAdapter {
"problems": {},
"codeActionOnSave": code_action_on_save,
"experimental": {
"useFlatConfig": workspace_root.join("eslint.config.js").is_file(),
"useFlatConfig": use_flat_config,
},
}
})
@@ -294,19 +302,13 @@ impl LspAdapter for EsLintLspAdapter {
async fn fetch_latest_server_version(
&self,
delegate: &dyn LspAdapterDelegate,
_delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
// We're using this hardcoded release tag, because ESLint's API changed with
// >= 2.3 and we haven't upgraded yet.
let release = github_release_with_tag(
"microsoft/vscode-eslint",
"release/2.2.20-Insider",
delegate.http_client(),
)
.await?;
let url = build_tarball_url("microsoft/vscode-eslint", Self::CURRENT_VERSION)?;
Ok(Box::new(GitHubLspBinaryVersion {
name: release.tag_name,
url: release.tarball_url,
name: Self::CURRENT_VERSION.into(),
url,
}))
}

View File

@@ -72,6 +72,14 @@ impl Model {
Self::FourTurbo => "gpt-4-turbo",
}
}
pub fn max_token_count(&self) -> usize {
match self {
Model::ThreePointFiveTurbo => 4096,
Model::Four => 8192,
Model::FourTurbo => 128000,
}
}
}
#[derive(Debug, Serialize)]

View File

@@ -183,7 +183,7 @@ async function handleMessage(message, prettier) {
...resolvedConfig,
plugins,
parser: params.options.parser,
path: params.options.filepath,
filepath: params.options.filepath,
};
process.stderr.write(
`Resolved config: ${JSON.stringify(resolvedConfig)}, will format file '${

View File

@@ -76,78 +76,33 @@ pub async fn latest_github_release(
.ok_or(anyhow!("Failed to find a release"))
}
pub async fn github_release_with_tag(
repo_name_with_owner: &str,
tag: &str,
http: Arc<dyn HttpClient>,
) -> Result<GithubRelease, anyhow::Error> {
let url = build_tagged_release_url(repo_name_with_owner, tag)?;
let mut response = http
.get(&url, Default::default(), true)
.await
.with_context(|| format!("error fetching release {} of {}", tag, repo_name_with_owner))?;
let mut body = Vec::new();
response
.body_mut()
.read_to_end(&mut body)
.await
.with_context(|| {
format!(
"error reading response body for release {} of {}",
tag, repo_name_with_owner
)
})?;
if response.status().is_client_error() {
let text = String::from_utf8_lossy(body.as_slice());
bail!(
"status error {}, response: {text:?}",
response.status().as_u16()
);
}
match serde_json::from_slice::<GithubRelease>(body.as_slice()) {
Ok(release) => Ok(release),
Err(err) => {
log::error!("Error deserializing: {:?}", err);
log::error!(
"GitHub API response text: {:?}",
String::from_utf8_lossy(body.as_slice())
);
Err(anyhow!(
"error deserializing release {} of {}",
tag,
repo_name_with_owner
))
}
}
}
fn build_tagged_release_url(repo_name_with_owner: &str, tag: &str) -> Result<String> {
pub fn build_tarball_url(repo_name_with_owner: &str, tag: &str) -> Result<String> {
let mut url = Url::parse(&format!(
"https://api.github.com/repos/{repo_name_with_owner}/releases/tags"
"https://github.com/{repo_name_with_owner}/archive/refs/tags",
))?;
// We're pushing this here, because tags may contain `/` and other characters
// that need to be escaped.
let tarball_filename = format!("{}.tar.gz", tag);
url.path_segments_mut()
.map_err(|_| anyhow!("cannot modify url path segments"))?
.push(tag);
.push(&tarball_filename);
Ok(url.to_string())
}
#[cfg(test)]
mod tests {
use super::build_tagged_release_url;
use crate::github::build_tarball_url;
#[test]
fn test_build_tagged_release_url() {
let tag = "release/2.2.20-Insider";
fn test_build_tarball_url() {
let tag = "release/2.3.5";
let repo_name_with_owner = "microsoft/vscode-eslint";
let have = build_tagged_release_url(repo_name_with_owner, tag).unwrap();
let have = build_tarball_url(repo_name_with_owner, tag).unwrap();
assert_eq!(have, "https://api.github.com/repos/microsoft/vscode-eslint/releases/tags/release%2F2.2.20-Insider");
assert_eq!(
have,
"https://github.com/microsoft/vscode-eslint/archive/refs/tags/release%2F2.3.5.tar.gz"
);
}
}

View File

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

View File

@@ -1 +1 @@
dev
stable