Compare commits

...

8 Commits

Author SHA1 Message Date
Zed Bot
4961830845 Bump to 0.193.2 for @SomeoneToIgnore 2025-06-27 16:45:08 +00:00
Kirill Bulatov
5a73af1af1 Respect server capabilities on queries (#33538)
Closes https://github.com/zed-industries/zed/issues/33522

Turns out a bunch of Zed requests were not checking their capabilities
correctly, due to odd copy-paste and due to default that assumed that
the capabilities are met.

Adjust the code, which includes the document colors, add the test on the
colors case.

Release Notes:

- Fixed excessive document colors requests for unrelated files
2025-06-27 19:41:14 +03:00
gcp-cherry-pick-bot[bot]
ebe2056745 Fix blend alpha colors with editor background in inline preview (cherry-pick #33513) (#33517)
Cherry-picked Fix blend alpha colors with editor background in inline
preview (#33513)

Closes #33505

## Before

<img width="434" alt="Screenshot 2025-06-27 at 12 22 57"

src="https://github.com/user-attachments/assets/ac215a39-b3fe-4c9e-bd7d-0d7568d5fd1f"
/>

## After

<img width="441" alt="Screenshot 2025-06-27 at 12 22 47"

src="https://github.com/user-attachments/assets/28218ed6-c1aa-4d3f-a268-def2fa9f0340"
/>

Release Notes:

- Fixed inline color previews not correctly blending alpha/transparency
values with the editor background

Co-authored-by: ddoemonn <109994179+ddoemonn@users.noreply.github.com>
2025-06-27 13:04:51 +03:00
gcp-cherry-pick-bot[bot]
a2b18a0b65 debugger: Fix treatment of node-terminal scenarios (cherry-pick #33432) (#33469)
Cherry-picked debugger: Fix treatment of node-terminal scenarios
(#33432)

- Normalize `node-terminal` to `pwa-node` before sending to DAP
- Split `command` into `program` and `args`
- Run in external console

Release Notes:

- debugger: Fixed debugging JavaScript tasks that used `"type":
"node-terminal"`.

Co-authored-by: Cole Miller <cole@zed.dev>
2025-06-26 15:02:51 -04:00
vipex
e0090a1680 pane: Update pinned tab count when it exceeds actual tab count (#33405)
## Summary

This PR improves the workaround introduced in #33335 that handles cases
where the pinned tab count exceeds the actual tab count during workspace
deserialization.

## Problem

The original workaround in #33335 successfully prevented the panic but
had two issues:
1. **Console spam**: The warning message was logged repeatedly because
`self.pinned_tab_count` wasn't updated to match the actual tab count
2. **Auto-pinning behavior**: New tabs up until you exceed the old safe
tab count were automatically pinned after the workaround was triggered.

## Solution

Updates the defensive code to set `self.pinned_tab_count = tab_count`
when the mismatch is detected, ensuring:
- The warning is only logged once when encountered.
- New tabs behave normally (aren't auto-pinned)
- The workspace remains in a consistent state

This is an immediate fix for the workaround. I'll attempt to open up a
follow-up PR when i get the chance that will address the root cause by
implementing serialization for empty untitled tabs, as discussed in
#33342.

Release Notes:

- N/A
2025-06-26 02:05:00 -04:00
Joseph T. Lyons
ca43498e10 zed 0.193.1 2025-06-25 19:05:50 -04:00
Max Brunsfeld
f315b6f1ed Restore missing initialization of text thread actions (#33422)
Fixes a regression introduced in
https://github.com/zed-industries/zed/pull/33289

Release Notes:

- Fixed a bug where some text thread actions were accidentally removed.
2025-06-25 15:52:58 -07:00
Joseph T. Lyons
6488524196 v0.193.x preview 2025-06-25 11:35:00 -04:00
14 changed files with 304 additions and 89 deletions

3
Cargo.lock generated
View File

@@ -4161,6 +4161,7 @@ dependencies = [
"paths",
"serde",
"serde_json",
"shlex",
"task",
"util",
"workspace-hack",
@@ -19919,7 +19920,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.193.0"
version = "0.193.2"
dependencies = [
"activity_indicator",
"agent",

View File

@@ -48,7 +48,7 @@ pub use crate::agent_panel::{AgentPanel, ConcreteAssistantPanelDelegate};
pub use crate::inline_assistant::InlineAssistant;
use crate::slash_command_settings::SlashCommandSettings;
pub use agent_diff::{AgentDiffPane, AgentDiffToolbar};
pub use text_thread_editor::AgentPanelDelegate;
pub use text_thread_editor::{AgentPanelDelegate, TextThreadEditor};
pub use ui::preview::{all_agent_previews, get_agent_preview};
actions!(
@@ -157,6 +157,7 @@ pub fn init(
agent::init(cx);
agent_panel::init(cx);
context_server_configuration::init(language_registry.clone(), fs.clone(), cx);
TextThreadEditor::init(cx);
register_slash_commands(cx);
inline_assistant::init(

View File

@@ -33,6 +33,7 @@ log.workspace = true
paths.workspace = true
serde.workspace = true
serde_json.workspace = true
shlex.workspace = true
task.workspace = true
util.workspace = true
workspace-hack.workspace = true

View File

@@ -5,7 +5,7 @@ use gpui::AsyncApp;
use serde_json::Value;
use std::{collections::HashMap, path::PathBuf, sync::OnceLock};
use task::DebugRequest;
use util::ResultExt;
use util::{ResultExt, maybe};
use crate::*;
@@ -72,6 +72,24 @@ impl JsDebugAdapter {
let mut configuration = task_definition.config.clone();
if let Some(configuration) = configuration.as_object_mut() {
maybe!({
configuration
.get("type")
.filter(|value| value == &"node-terminal")?;
let command = configuration.get("command")?.as_str()?.to_owned();
let mut args = shlex::split(&command)?.into_iter();
let program = args.next()?;
configuration.insert("program".to_owned(), program.into());
configuration.insert(
"args".to_owned(),
args.map(Value::from).collect::<Vec<_>>().into(),
);
configuration.insert("console".to_owned(), "externalTerminal".into());
Some(())
});
configuration.entry("type").and_modify(normalize_task_type);
if let Some(program) = configuration
.get("program")
.cloned()
@@ -96,7 +114,6 @@ impl JsDebugAdapter {
.entry("cwd")
.or_insert(delegate.worktree_root_path().to_string_lossy().into());
configuration.entry("type").and_modify(normalize_task_type);
configuration
.entry("console")
.or_insert("externalTerminal".into());
@@ -512,7 +529,7 @@ fn normalize_task_type(task_type: &mut Value) {
};
let new_name = match task_type_str {
"node" | "pwa-node" => "pwa-node",
"node" | "pwa-node" | "node-terminal" => "pwa-node",
"chrome" | "pwa-chrome" => "pwa-chrome",
"edge" | "msedge" | "pwa-edge" | "pwa-msedge" => "pwa-msedge",
_ => task_type_str,

View File

@@ -966,10 +966,22 @@ impl DisplaySnapshot {
.and_then(|id| id.style(&editor_style.syntax));
if let Some(chunk_highlight) = chunk.highlight_style {
// For color inlays, blend the color with the editor background
let mut processed_highlight = chunk_highlight;
if chunk.is_inlay {
if let Some(inlay_color) = chunk_highlight.color {
// Only blend if the color has transparency (alpha < 1.0)
if inlay_color.a < 1.0 {
let blended_color = editor_style.background.blend(inlay_color);
processed_highlight.color = Some(blended_color);
}
}
}
if let Some(highlight_style) = highlight_style.as_mut() {
highlight_style.highlight(chunk_highlight);
highlight_style.highlight(processed_highlight);
} else {
highlight_style = Some(chunk_highlight);
highlight_style = Some(processed_highlight);
}
}

View File

@@ -22580,6 +22580,18 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
color_provider: Some(lsp::ColorProviderCapability::Simple(true)),
..lsp::ServerCapabilities::default()
},
name: "rust-analyzer",
..FakeLspAdapter::default()
},
);
let mut fake_servers_without_capabilities = language_registry.register_fake_lsp(
"Rust",
FakeLspAdapter {
capabilities: lsp::ServerCapabilities {
color_provider: Some(lsp::ColorProviderCapability::Simple(false)),
..lsp::ServerCapabilities::default()
},
name: "not-rust-analyzer",
..FakeLspAdapter::default()
},
);
@@ -22599,6 +22611,8 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
.downcast::<Editor>()
.unwrap();
let fake_language_server = fake_servers.next().await.unwrap();
let fake_language_server_without_capabilities =
fake_servers_without_capabilities.next().await.unwrap();
let requests_made = Arc::new(AtomicUsize::new(0));
let closure_requests_made = Arc::clone(&requests_made);
let mut color_request_handle = fake_language_server
@@ -22610,34 +22624,59 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
lsp::Url::from_file_path(path!("/a/first.rs")).unwrap()
);
requests_made.fetch_add(1, atomic::Ordering::Release);
Ok(vec![lsp::ColorInformation {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 0,
Ok(vec![
lsp::ColorInformation {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 0,
},
end: lsp::Position {
line: 0,
character: 1,
},
},
end: lsp::Position {
line: 0,
character: 1,
color: lsp::Color {
red: 0.33,
green: 0.33,
blue: 0.33,
alpha: 0.33,
},
},
color: lsp::Color {
red: 0.33,
green: 0.33,
blue: 0.33,
alpha: 0.33,
lsp::ColorInformation {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 0,
},
end: lsp::Position {
line: 0,
character: 1,
},
},
color: lsp::Color {
red: 0.33,
green: 0.33,
blue: 0.33,
alpha: 0.33,
},
},
}])
])
}
});
let _handle = fake_language_server_without_capabilities
.set_request_handler::<lsp::request::DocumentColor, _, _>(move |_, _| async move {
panic!("Should not be called");
});
color_request_handle.next().await.unwrap();
cx.run_until_parked();
color_request_handle.next().await.unwrap();
cx.run_until_parked();
assert_eq!(
2,
3,
requests_made.load(atomic::Ordering::Acquire),
"Should query for colors once per editor open and once after the language server startup"
"Should query for colors once per editor open (1) and once after the language server startup (2)"
);
cx.executor().advance_clock(Duration::from_millis(500));
@@ -22667,7 +22706,7 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
color_request_handle.next().await.unwrap();
cx.run_until_parked();
assert_eq!(
4,
5,
requests_made.load(atomic::Ordering::Acquire),
"Should query for colors once per save and once per formatting after save"
);
@@ -22682,7 +22721,7 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
.unwrap();
close.await.unwrap();
assert_eq!(
4,
5,
requests_made.load(atomic::Ordering::Acquire),
"After saving and closing the editor, no extra requests should be made"
);
@@ -22694,10 +22733,11 @@ async fn test_mtime_and_document_colors(cx: &mut TestAppContext) {
})
})
.unwrap();
cx.executor().advance_clock(Duration::from_millis(100));
color_request_handle.next().await.unwrap();
cx.run_until_parked();
assert_eq!(
5,
6,
requests_made.load(atomic::Ordering::Acquire),
"After navigating back to an editor and reopening it, another color request should be made"
);

View File

@@ -107,9 +107,7 @@ pub trait LspCommand: 'static + Sized + Send + std::fmt::Debug {
}
/// When false, `to_lsp_params_or_response` default implementation will return the default response.
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool;
fn to_lsp(
&self,
@@ -277,6 +275,16 @@ impl LspCommand for PrepareRename {
"Prepare rename"
}
fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
capabilities
.server_capabilities
.rename_provider
.is_some_and(|capability| match capability {
OneOf::Left(enabled) => enabled,
OneOf::Right(options) => options.prepare_provider.unwrap_or(false),
})
}
fn to_lsp_params_or_response(
&self,
path: &Path,
@@ -459,6 +467,16 @@ impl LspCommand for PerformRename {
"Rename"
}
fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
capabilities
.server_capabilities
.rename_provider
.is_some_and(|capability| match capability {
OneOf::Left(enabled) => enabled,
OneOf::Right(_options) => true,
})
}
fn to_lsp(
&self,
path: &Path,
@@ -583,7 +601,10 @@ impl LspCommand for GetDefinition {
capabilities
.server_capabilities
.definition_provider
.is_some()
.is_some_and(|capability| match capability {
OneOf::Left(supported) => supported,
OneOf::Right(_options) => true,
})
}
fn to_lsp(
@@ -682,7 +703,11 @@ impl LspCommand for GetDeclaration {
capabilities
.server_capabilities
.declaration_provider
.is_some()
.is_some_and(|capability| match capability {
lsp::DeclarationCapability::Simple(supported) => supported,
lsp::DeclarationCapability::RegistrationOptions(..) => true,
lsp::DeclarationCapability::Options(..) => true,
})
}
fn to_lsp(
@@ -777,6 +802,16 @@ impl LspCommand for GetImplementation {
"Get implementation"
}
fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
capabilities
.server_capabilities
.implementation_provider
.is_some_and(|capability| match capability {
lsp::ImplementationProviderCapability::Simple(enabled) => enabled,
lsp::ImplementationProviderCapability::Options(_options) => true,
})
}
fn to_lsp(
&self,
path: &Path,
@@ -1437,7 +1472,10 @@ impl LspCommand for GetDocumentHighlights {
capabilities
.server_capabilities
.document_highlight_provider
.is_some()
.is_some_and(|capability| match capability {
OneOf::Left(supported) => supported,
OneOf::Right(_options) => true,
})
}
fn to_lsp(
@@ -1590,7 +1628,10 @@ impl LspCommand for GetDocumentSymbols {
capabilities
.server_capabilities
.document_symbol_provider
.is_some()
.is_some_and(|capability| match capability {
OneOf::Left(supported) => supported,
OneOf::Right(_options) => true,
})
}
fn to_lsp(
@@ -2116,6 +2157,13 @@ impl LspCommand for GetCompletions {
"Get completion"
}
fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
capabilities
.server_capabilities
.completion_provider
.is_some()
}
fn to_lsp(
&self,
path: &Path,
@@ -4161,7 +4209,11 @@ impl LspCommand for GetDocumentColor {
server_capabilities
.server_capabilities
.color_provider
.is_some()
.is_some_and(|capability| match capability {
lsp::ColorProviderCapability::Simple(supported) => supported,
lsp::ColorProviderCapability::ColorProvider(..) => true,
lsp::ColorProviderCapability::Options(..) => true,
})
}
fn to_lsp(

View File

@@ -3488,7 +3488,8 @@ pub struct LspStore {
lsp_data: Option<LspData>,
}
type DocumentColorTask = Shared<Task<std::result::Result<Vec<DocumentColor>, Arc<anyhow::Error>>>>;
type DocumentColorTask =
Shared<Task<std::result::Result<HashSet<DocumentColor>, Arc<anyhow::Error>>>>;
#[derive(Debug)]
struct LspData {
@@ -3500,7 +3501,7 @@ struct LspData {
#[derive(Debug, Default)]
struct BufferLspData {
colors: Option<Vec<DocumentColor>>,
colors: Option<HashSet<DocumentColor>>,
}
pub enum LspStoreEvent {
@@ -6123,13 +6124,13 @@ impl LspStore {
.flat_map(|lsp_data| lsp_data.buffer_lsp_data.values())
.filter_map(|buffer_data| buffer_data.get(&abs_path))
.filter_map(|buffer_data| {
let colors = buffer_data.colors.as_deref()?;
let colors = buffer_data.colors.as_ref()?;
received_colors_data = true;
Some(colors)
})
.flatten()
.cloned()
.collect::<Vec<_>>();
.collect::<HashSet<_>>();
if buffer_lsp_data.is_empty() || for_server_id.is_some() {
if received_colors_data && for_server_id.is_none() {
@@ -6183,42 +6184,25 @@ impl LspStore {
let task_abs_path = abs_path.clone();
let new_task = cx
.spawn(async move |lsp_store, cx| {
cx.background_executor().timer(Duration::from_millis(50)).await;
let fetched_colors = match lsp_store
.update(cx, |lsp_store, cx| {
lsp_store.fetch_document_colors(buffer, cx)
}) {
Ok(fetch_task) => fetch_task.await
.with_context(|| {
format!(
"Fetching document colors for buffer with path {task_abs_path:?}"
)
}),
Err(e) => return Err(Arc::new(e)),
};
let fetched_colors = match fetched_colors {
Ok(fetched_colors) => fetched_colors,
Err(e) => return Err(Arc::new(e)),
};
let lsp_colors = lsp_store.update(cx, |lsp_store, _| {
let lsp_data = lsp_store.lsp_data.as_mut().with_context(|| format!(
"Document lsp data got updated between fetch and update for path {task_abs_path:?}"
))?;
let mut lsp_colors = Vec::new();
anyhow::ensure!(lsp_data.mtime == buffer_mtime, "Buffer lsp data got updated between fetch and update for path {task_abs_path:?}");
for (server_id, colors) in fetched_colors {
let colors_lsp_data = &mut lsp_data.buffer_lsp_data.entry(server_id).or_default().entry(task_abs_path.clone()).or_default().colors;
*colors_lsp_data = Some(colors.clone());
lsp_colors.extend(colors);
match fetch_document_colors(
lsp_store.clone(),
buffer,
task_abs_path.clone(),
cx,
)
.await
{
Ok(colors) => Ok(colors),
Err(e) => {
lsp_store
.update(cx, |lsp_store, _| {
if let Some(lsp_data) = lsp_store.lsp_data.as_mut() {
lsp_data.colors_update.remove(&task_abs_path);
}
})
.ok();
Err(Arc::new(e))
}
Ok(lsp_colors)
});
match lsp_colors {
Ok(Ok(lsp_colors)) => Ok(lsp_colors),
Ok(Err(e)) => Err(Arc::new(e)),
Err(e) => Err(Arc::new(e)),
}
})
.shared();
@@ -6236,11 +6220,11 @@ impl LspStore {
}
}
fn fetch_document_colors(
fn fetch_document_colors_for_buffer(
&mut self,
buffer: Entity<Buffer>,
cx: &mut Context<Self>,
) -> Task<anyhow::Result<Vec<(LanguageServerId, Vec<DocumentColor>)>>> {
) -> Task<anyhow::Result<Vec<(LanguageServerId, HashSet<DocumentColor>)>>> {
if let Some((client, project_id)) = self.upstream_client() {
let request_task = client.request(proto::MultiLspQuery {
project_id,
@@ -6289,7 +6273,9 @@ impl LspStore {
.await
.into_iter()
.fold(HashMap::default(), |mut acc, (server_id, colors)| {
acc.entry(server_id).or_insert_with(Vec::new).extend(colors);
acc.entry(server_id)
.or_insert_with(HashSet::default)
.extend(colors);
acc
})
.into_iter()
@@ -6304,7 +6290,9 @@ impl LspStore {
.await
.into_iter()
.fold(HashMap::default(), |mut acc, (server_id, colors)| {
acc.entry(server_id).or_insert_with(Vec::new).extend(colors);
acc.entry(server_id)
.or_insert_with(HashSet::default)
.extend(colors);
acc
})
.into_iter()
@@ -10331,6 +10319,53 @@ impl LspStore {
}
}
async fn fetch_document_colors(
lsp_store: WeakEntity<LspStore>,
buffer: Entity<Buffer>,
task_abs_path: PathBuf,
cx: &mut AsyncApp,
) -> anyhow::Result<HashSet<DocumentColor>> {
cx.background_executor()
.timer(Duration::from_millis(50))
.await;
let Some(buffer_mtime) = buffer.update(cx, |buffer, _| buffer.saved_mtime())? else {
return Ok(HashSet::default());
};
let fetched_colors = lsp_store
.update(cx, |lsp_store, cx| {
lsp_store.fetch_document_colors_for_buffer(buffer, cx)
})?
.await
.with_context(|| {
format!("Fetching document colors for buffer with path {task_abs_path:?}")
})?;
lsp_store.update(cx, |lsp_store, _| {
let lsp_data = lsp_store.lsp_data.as_mut().with_context(|| {
format!(
"Document lsp data got updated between fetch and update for path {task_abs_path:?}"
)
})?;
let mut lsp_colors = HashSet::default();
anyhow::ensure!(
lsp_data.mtime == buffer_mtime,
"Buffer lsp data got updated between fetch and update for path {task_abs_path:?}"
);
for (server_id, colors) in fetched_colors {
let colors_lsp_data = &mut lsp_data
.buffer_lsp_data
.entry(server_id)
.or_default()
.entry(task_abs_path.clone())
.or_default()
.colors;
*colors_lsp_data = Some(colors.clone());
lsp_colors.extend(colors);
}
Ok(lsp_colors)
})?
}
fn lsp_workspace_diagnostics_refresh(
server: Arc<LanguageServer>,
cx: &mut Context<'_, LspStore>,

View File

@@ -16,7 +16,7 @@ use language::{
Buffer, point_to_lsp,
proto::{deserialize_anchor, serialize_anchor},
};
use lsp::{LanguageServer, LanguageServerId};
use lsp::{AdapterServerCapabilities, LanguageServer, LanguageServerId};
use rpc::proto::{self, PeerId};
use serde::{Deserialize, Serialize};
use std::{
@@ -68,6 +68,10 @@ impl LspCommand for ExpandMacro {
"Expand macro"
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn to_lsp(
&self,
path: &Path,
@@ -196,6 +200,10 @@ impl LspCommand for OpenDocs {
"Open docs"
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn to_lsp(
&self,
path: &Path,
@@ -326,6 +334,10 @@ impl LspCommand for SwitchSourceHeader {
"Switch source header"
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn to_lsp(
&self,
path: &Path,
@@ -404,6 +416,10 @@ impl LspCommand for GoToParentModule {
"Go to parent module"
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn to_lsp(
&self,
path: &Path,
@@ -578,6 +594,10 @@ impl LspCommand for GetLspRunnables {
"LSP Runnables"
}
fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
true
}
fn to_lsp(
&self,
path: &Path,

View File

@@ -778,13 +778,42 @@ pub struct DocumentColor {
pub color_presentations: Vec<ColorPresentation>,
}
#[derive(Clone, Debug, PartialEq)]
impl Eq for DocumentColor {}
impl std::hash::Hash for DocumentColor {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.lsp_range.hash(state);
self.color.red.to_bits().hash(state);
self.color.green.to_bits().hash(state);
self.color.blue.to_bits().hash(state);
self.color.alpha.to_bits().hash(state);
self.resolved.hash(state);
self.color_presentations.hash(state);
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ColorPresentation {
pub label: String,
pub text_edit: Option<lsp::TextEdit>,
pub additional_text_edits: Vec<lsp::TextEdit>,
}
impl std::hash::Hash for ColorPresentation {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.label.hash(state);
if let Some(ref edit) = self.text_edit {
edit.range.hash(state);
edit.new_text.hash(state);
}
self.additional_text_edits.len().hash(state);
for edit in &self.additional_text_edits {
edit.range.hash(state);
edit.new_text.hash(state);
}
}
}
#[derive(Clone)]
pub enum DirectoryLister {
Project(Entity<Project>),

View File

@@ -422,7 +422,12 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
"Rust",
FakeLspAdapter {
name: "rust-analyzer",
..Default::default()
capabilities: lsp::ServerCapabilities {
completion_provider: Some(lsp::CompletionOptions::default()),
rename_provider: Some(lsp::OneOf::Left(true)),
..lsp::ServerCapabilities::default()
},
..FakeLspAdapter::default()
},
)
});
@@ -430,7 +435,11 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
let mut fake_lsp = server_cx.update(|cx| {
headless.read(cx).languages.register_fake_language_server(
LanguageServerName("rust-analyzer".into()),
Default::default(),
lsp::ServerCapabilities {
completion_provider: Some(lsp::CompletionOptions::default()),
rename_provider: Some(lsp::OneOf::Left(true)),
..lsp::ServerCapabilities::default()
},
None,
)
});

View File

@@ -2784,7 +2784,7 @@ impl Pane {
})
.collect::<Vec<_>>();
let tab_count = tab_items.len();
let safe_pinned_count = if self.pinned_tab_count > tab_count {
if self.pinned_tab_count > tab_count {
log::warn!(
"Pinned tab count ({}) exceeds actual tab count ({}). \
This should not happen. If possible, add reproduction steps, \
@@ -2792,11 +2792,9 @@ impl Pane {
self.pinned_tab_count,
tab_count
);
tab_count
} else {
self.pinned_tab_count
};
let unpinned_tabs = tab_items.split_off(safe_pinned_count);
self.pinned_tab_count = tab_count;
}
let unpinned_tabs = tab_items.split_off(self.pinned_tab_count);
let pinned_tabs = tab_items;
TabBar::new("tab_bar")
.when(

View File

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

View File

@@ -1 +1 @@
dev
preview