Compare commits

...

17 Commits

Author SHA1 Message Date
Antonio Scandurra
a2ab5eab81 zed 0.142.5 2024-07-04 10:21:02 +02:00
gcp-cherry-pick-bot[bot]
beadb11a2f Improve prompt for Claude models (cherry-pick #13531) (#13816)
Cherry-picked Improve prompt for Claude models (#13531)

This inline assistant prompt is one I designed that in my experience
works much better with Claude 3.5 Sonnet than the default prompt.

Mainly because it takes advantage of a weird property of our finetuning
which is that when you use XML tags it knows that it's doing a
machine-read tasks and stops trying to elide things for brevity. The
default prompt will often remove comments and otherwise add elisions for
brevity when doing large rewrites.

It also avoids giving the entire file content twice when the rewrite
region is large relative to the non-rewritten region.

Not necessarily meant to be merged as-is since it may mess up OAI
models. This is mainly meant for your reference. But everyone should be
using 3.5 Sonnet for coding use cases now anyhow 😛

Release Notes:

- Improved inline assistant code generation when using Claude or GPT-4o.

Co-authored-by: Tristan Hume <tristan@anthropic.com>
2024-07-04 10:19:08 +02:00
Peter Tripp
f7eca9ec9e v0.142.x stable 2024-07-03 12:15:06 -04:00
Zed Bot
5a2c5d2512 Bump to 0.142.4 for @osiewicz 2024-07-03 02:23:57 -07:00
Aleksei Gusev
7cdf702819 Fix PageUp for context menu (#13593)
The PageUp key was not working for the context menu. Instead of
selecting one of the previous items in the context menu, `MovePageUp`
closed the menu and scrolled the editor. `MovePageDown` was working
correctly because it has the same fix.



Release Notes:

- Fixed `pageup` key, when bound to `editor::MovePageUp`, not moving context menus as other keys
2024-07-02 02:54:46 +03:00
Yongkang Chen
34d7f1e345 Store starts open state of outline panel (#13601)
- Fixed issue where outline panel remains open despite being closed
before window close.

Before the release of Outline Panel feature, everything works fine. But
after that, the outline panel keeps open. It's very annoy that I only
want to edit a simple file. Event I close it before I close the window.
The active state of this panel didn't stored.

### Description:
Before the introduction of the Outline Panel feature, the application
behaved as expected. However, with the addition of the Outline Panel, an
issue arose where the panel would persistently remain open. This
behavior was observed even when manually closing the panel before
closing the application window. The problem stemmed from the inactive
state of the panel not being stored properly. This fix addresses the
issue by ensuring that the panel's active state is correctly stored and
retrieved, thereby improving user experience and preventing unnecessary
persistence of the panel's visibility.

### Screen Records

#### Before Release of Outline Panel


https://github.com/zed-industries/zed/assets/704762/2a222c70-c6d7-4472-9f27-7868d1786a5f


#### After Release of Outline Panel


https://github.com/zed-industries/zed/assets/704762/69c16a5d-beed-4d4a-8341-83c53f6a6713


#### After Fixing This Issue


https://github.com/zed-industries/zed/assets/704762/f51c5df7-54e3-4a62-ac54-b5d12cfe69d1

### Release Notes:

- Persist outline panel open state to avoid opening it on Zed startup
2024-07-02 02:54:29 +03:00
Kirill Bulatov
53730e2aaa Fix Prettier parser values when formatting files with paths (#13666)
Closes https://github.com/zed-industries/zed/issues/13660

Now, as intended, the parser value is passed only if configured in the
language settings.

Also, allows to format JSONC by default with Prettier and reformats Zed
settings.

Release Notes:

- Fixed Zed Prettier integration always passing parser value for files
with paths ([13660](https://github.com/zed-industries/zed/issues/13660))
2024-07-02 02:54:08 +03:00
Peter Tripp
b48cc75fa9 zed 0.142.3 2024-06-28 09:19:34 -04:00
Nathan Sobo
071650ff61 Fix a stupid bug that was dropping system prompts for Claude (#13626)
Release Notes:

- Fixed a bug that was causing system prompts to be dropped for
Anthropic models.

@JosephTLyons @notpeter We probably need to hot-fix this as I'm pretty
sure this affects the regular anthropic provider in addition to just the
feature-flagged cloud stuff. Wouldn't mind confirming that first so we
can communicate around it. 😬
2024-06-28 09:19:01 -04:00
Zed Bot
86183ca65d Bump to 0.142.2 for @ConradIrwin 2024-06-27 16:00:52 -07:00
gcp-cherry-pick-bot[bot]
075860d5cd Fix multi-keystroke shortcuts better (cherry-pick #13612) (#13614)
Cherry-picked Fix multi-keystroke shortcuts better (#13612)

Release Notes:

- N/A

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-06-27 16:55:22 -06:00
gcp-cherry-pick-bot[bot]
67ba048581 Fix multi-key shortcuts (cherry-pick #13606) (#13607)
Cherry-picked Fix multi-key shortcuts (#13606)

Broken by the shift shift support PR

Release Notes:

- Fix multi-key shortcuts (preview only)

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-06-27 15:32:57 -06:00
Peter Tripp
d5fb290499 Release notes upload fix (#13560)
- Action for release notes upload (softprops/action-gh-release) configured with incorrect key. 
- Valid keys here: https://github.com/softprops/action-gh-release?tab=readme-ov-file#-customizing
2024-06-27 14:40:28 -06:00
gcp-cherry-pick-bot[bot]
b01945e1de fix panics (cherry-pick #13554) (#13558)
Cherry-picked fix panics (#13554)

Release Notes:

- Fixed a panic when editing HTML near the end of a file
- Fixed a panic when editing settings.json from inside the .zed
directory

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-06-26 16:27:45 -06:00
Peter Tripp
1b0b7fe064 zed 0.142.1 2024-06-26 16:23:22 -04:00
Piotr Osiewicz
985644bacb json: Fix package-version-server referencing the wrong path to the binary (#13555)
We were trying to access the binary at
package-version-server-{VERSION}/package-version-server, whereas the
binary itself is placed at package-version-server-{VERSION}

Release Notes:

- Fixed package.json language server failing to start.

Co-authored-by: Peter Tripp <peter@zed.dev>
2024-06-26 16:21:51 -04:00
Peter Tripp
c686c4c800 v0.142.x preview 2024-06-26 12:19:49 -04:00
13 changed files with 148 additions and 130 deletions

View File

@@ -254,7 +254,7 @@ jobs:
target/aarch64-apple-darwin/release/Zed-aarch64.dmg
target/x86_64-apple-darwin/release/Zed-x86_64.dmg
target/release/Zed.dmg
body_file: target/release-notes.md
body_path: target/release-notes.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2
Cargo.lock generated
View File

@@ -13550,7 +13550,7 @@ dependencies = [
[[package]]
name = "zed"
version = "0.142.0"
version = "0.142.5"
dependencies = [
"activity_indicator",
"anyhow",

View File

@@ -131,14 +131,7 @@
// The default number of lines to expand excerpts in the multibuffer by.
"expand_excerpt_lines": 3,
// Globs to match against file paths to determine if a file is private.
"private_files": [
"**/.env*",
"**/*.pem",
"**/*.key",
"**/*.cert",
"**/*.crt",
"**/secrets.yml"
],
"private_files": ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/secrets.yml"],
// Whether to use additional LSP queries to format (and amend) the code after
// every "trigger" symbol input, defined by LSP server capabilities.
"use_on_type_format": true,
@@ -758,6 +751,11 @@
"allowed": true
}
},
"JSONC": {
"prettier": {
"allowed": true
}
},
"Markdown": {
"format_on_save": "off",
"prettier": {

View File

@@ -236,7 +236,7 @@ pub fn preprocess_anthropic_request(request: &mut LanguageModelRequest) {
}
if !system_message.is_empty() {
request.messages.insert(
new_messages.insert(
0,
LanguageModelRequestMessage {
role: Role::System,

View File

@@ -6,118 +6,106 @@ pub fn generate_content_prompt(
language_name: Option<&str>,
buffer: BufferSnapshot,
range: Range<usize>,
project_name: Option<String>,
_project_name: Option<String>,
) -> anyhow::Result<String> {
let mut prompt = String::new();
let content_type = match language_name {
None | Some("Markdown" | "Plain Text") => {
writeln!(prompt, "You are an expert engineer.")?;
"Text"
}
Some(language_name) => {
writeln!(prompt, "You are an expert {language_name} engineer.")?;
writeln!(
prompt,
"Your answer MUST always and only be valid {}.",
language_name
"Here's a file of text that I'm going to ask you to make an edit to."
)?;
"Code"
"text"
}
Some(language_name) => {
writeln!(
prompt,
"Here's a file of {language_name} that I'm going to ask you to make an edit to."
)?;
"code"
}
};
if let Some(project_name) = project_name {
writeln!(
prompt,
"You are currently working inside the '{project_name}' project in code editor Zed."
)?;
}
writeln!(
prompt,
"The user has the following file open in the editor:"
)?;
const MAX_CTX: usize = 50000;
let mut is_truncated = false;
if range.is_empty() {
write!(prompt, "```")?;
if let Some(language_name) = language_name {
write!(prompt, "{language_name}")?;
}
for chunk in buffer.as_rope().chunks_in_range(0..range.start) {
prompt.push_str(chunk);
}
prompt.push_str("<|CURSOR|>");
for chunk in buffer.as_rope().chunks_in_range(range.start..buffer.len()) {
prompt.push_str(chunk);
}
if !prompt.ends_with('\n') {
prompt.push('\n');
}
writeln!(prompt, "```")?;
prompt.push('\n');
writeln!(
prompt,
"Assume the cursor is located where the `<|CURSOR|>` span is."
)
.unwrap();
writeln!(
prompt,
"{content_type} can't be replaced, so assume your answer will be inserted at the cursor.",
)
.unwrap();
writeln!(
prompt,
"Generate {content_type} based on the users prompt: {user_prompt}",
)
.unwrap();
prompt.push_str("The point you'll need to insert at is marked with <insert_here></insert_here>.\n\n<document>");
} else {
write!(prompt, "```")?;
for chunk in buffer.as_rope().chunks() {
prompt.push_str(chunk);
}
if !prompt.ends_with('\n') {
prompt.push('\n');
}
writeln!(prompt, "```")?;
prompt.push('\n');
writeln!(
prompt,
"In particular, the following piece of text is selected:"
)?;
write!(prompt, "```")?;
if let Some(language_name) = language_name {
write!(prompt, "{language_name}")?;
}
prompt.push('\n');
prompt.push_str("The section you'll need to rewrite is marked with <rewrite_this></rewrite_this> tags.\n\n<document>");
}
// Include file content.
let before_range = 0..range.start;
let truncated_before = if before_range.len() > MAX_CTX {
is_truncated = true;
range.start - MAX_CTX..range.start
} else {
before_range
};
let mut non_rewrite_len = truncated_before.len();
for chunk in buffer.text_for_range(truncated_before) {
prompt.push_str(chunk);
}
if !range.is_empty() {
prompt.push_str("<rewrite_this>\n");
for chunk in buffer.text_for_range(range.clone()) {
prompt.push_str(chunk);
}
if !prompt.ends_with('\n') {
prompt.push('\n');
}
writeln!(prompt, "```")?;
prompt.push('\n');
writeln!(
prompt,
"Modify the user's selected {content_type} based upon the users prompt: {user_prompt}"
)
.unwrap();
writeln!(
prompt,
"You must reply with only the adjusted {content_type}, not the entire file."
)
.unwrap();
prompt.push_str("\n<rewrite_this>");
} else {
prompt.push_str("<insert_here></insert_here>");
}
let after_range = range.end..buffer.len();
let truncated_after = if after_range.len() > MAX_CTX {
is_truncated = true;
range.end..range.end + MAX_CTX
} else {
after_range
};
non_rewrite_len += truncated_after.len();
for chunk in buffer.text_for_range(truncated_after) {
prompt.push_str(chunk);
}
writeln!(prompt, "Never make remarks about the output.").unwrap();
writeln!(
prompt,
"Do not return anything else, except the generated {content_type}."
)
.unwrap();
write!(prompt, "</document>\n\n").unwrap();
if is_truncated {
writeln!(prompt, "The context around the relevant section has been truncated (possibly in the middle of a line) for brevity.\n")?;
}
if range.is_empty() {
writeln!(
prompt,
"You can't replace {content_type}, your answer will be inserted in place of the `<insert_here></insert_here>` tags. Don't include the insert_here tags in your output.",
)
.unwrap();
writeln!(
prompt,
"Generate {content_type} based on the following prompt:\n\n<prompt>\n{user_prompt}\n</prompt>",
)
.unwrap();
writeln!(prompt, "Match the indentation in the original file in the inserted {content_type}, don't include any indentation on blank lines.\n").unwrap();
prompt.push_str("Immediately start with the following format with no remarks:\n\n```\n{{INSERTED_CODE}}\n```");
} else {
writeln!(prompt, "Edit the section of {content_type} in <rewrite_this></rewrite_this> tags based on the following prompt:'").unwrap();
writeln!(prompt, "\n<prompt>\n{user_prompt}\n</prompt>\n").unwrap();
let rewrite_len = range.end - range.start;
if rewrite_len < 20000 && rewrite_len * 2 < non_rewrite_len {
writeln!(prompt, "And here's the section to rewrite based on that prompt again for reference:\n\n<rewrite_this>\n").unwrap();
for chunk in buffer.text_for_range(range.clone()) {
prompt.push_str(chunk);
}
writeln!(prompt, "\n</rewrite_this>\n").unwrap();
}
writeln!(prompt, "Only make changes that are necessary to fulfill the prompt, leave everything else as-is. All surrounding {content_type} will be preserved.\n").unwrap();
write!(
prompt,
"Start at the indentation level in the original file in the rewritten {content_type}. "
)
.unwrap();
prompt.push_str("Don't stop until you've rewritten the entire section, even if you have no more changes to make, always write out the whole section with no unnecessary elisions.");
prompt.push_str("\n\nImmediately start with the following format with no remarks:\n\n```\n{{REWRITTEN_CODE}}\n```");
}
Ok(prompt)
}

View File

@@ -2914,6 +2914,9 @@ impl Editor {
let start_offset = TO::to_offset(&range.start, &buffer_snapshot);
let end_offset = start_offset + end_difference;
let start_offset = start_offset + start_difference;
if start_offset > buffer_snapshot.len() || end_offset > buffer_snapshot.len() {
continue;
}
let start = buffer_snapshot.anchor_after(start_offset);
let end = buffer_snapshot.anchor_after(end_offset);
linked_edits
@@ -6809,6 +6812,16 @@ impl Editor {
return;
}
if self
.context_menu
.write()
.as_mut()
.map(|menu| menu.select_first(self.project.as_ref(), cx))
.unwrap_or(false)
{
return;
}
if matches!(self.mode, EditorMode::SingleLine { .. }) {
cx.propagate();
return;

View File

@@ -549,11 +549,17 @@ pub struct Window {
pub(crate) focus: Option<FocusId>,
focus_enabled: bool,
pending_input: Option<PendingInput>,
pending_modifiers: Option<Modifiers>,
pending_modifier: ModifierState,
pending_input_observers: SubscriberSet<(), AnyObserver>,
prompt: Option<RenderablePromptHandle>,
}
#[derive(Clone, Debug, Default)]
struct ModifierState {
modifiers: Modifiers,
saw_keystroke: bool,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum DrawPhase {
None,
@@ -824,7 +830,7 @@ impl Window {
focus: None,
focus_enabled: true,
pending_input: None,
pending_modifiers: None,
pending_modifier: ModifierState::default(),
pending_input_observers: SubscriberSet::new(),
prompt: None,
})
@@ -3168,9 +3174,12 @@ impl<'a> WindowContext<'a> {
let mut keystroke: Option<Keystroke> = None;
if let Some(event) = event.downcast_ref::<ModifiersChangedEvent>() {
if let Some(previous) = self.window.pending_modifiers.take() {
if event.modifiers.number_of_modifiers() == 0
&& self.window.pending_modifier.modifiers.number_of_modifiers() == 1
&& !self.window.pending_modifier.saw_keystroke
{
if event.modifiers.number_of_modifiers() == 0 {
let key = match previous {
let key = match self.window.pending_modifier.modifiers {
modifiers if modifiers.shift => Some("shift"),
modifiers if modifiers.control => Some("control"),
modifiers if modifiers.alt => Some("alt"),
@@ -3198,17 +3207,15 @@ impl<'a> WindowContext<'a> {
pending = pending_bindings;
}
}
} else if event.modifiers.number_of_modifiers() == 1 {
self.window.pending_modifiers = Some(event.modifiers);
}
if keystroke.is_none() {
self.finish_dispatch_key_event(event, dispatch_path);
return;
if self.window.pending_modifier.modifiers.number_of_modifiers() == 0
&& event.modifiers.number_of_modifiers() == 1
{
self.window.pending_modifier.saw_keystroke = false
}
}
if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
self.window.pending_modifiers.take();
self.window.pending_modifier.modifiers = event.modifiers
} else if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
self.window.pending_modifier.saw_keystroke = true;
let KeymatchResult {
bindings: key_down_bindings,
pending: key_down_pending,
@@ -3224,6 +3231,11 @@ impl<'a> WindowContext<'a> {
pending = key_down_pending;
}
if keystroke.is_none() {
self.finish_dispatch_key_event(event, dispatch_path);
return;
}
if pending {
let mut currently_pending = self.window.pending_input.take().unwrap_or_default();
if currently_pending.focus.is_some() && currently_pending.focus != self.window.focus {

View File

@@ -348,7 +348,7 @@ impl LspAdapter for NodeVersionAdapter {
}
Ok(LanguageServerBinary {
path: destination_path.join("package-version-server"),
path: destination_path,
env: None,
arguments: Default::default(),
})

View File

@@ -272,6 +272,7 @@ pub enum Event {
#[derive(Serialize, Deserialize)]
struct SerializedOutlinePanel {
width: Option<Pixels>,
active: Option<bool>,
}
pub fn init_settings(cx: &mut AppContext) {
@@ -312,6 +313,7 @@ impl OutlinePanel {
if let Some(serialized_panel) = serialized_panel {
panel.update(cx, |panel, cx| {
panel.width = serialized_panel.width.map(|px| px.round());
panel.active = serialized_panel.active.unwrap_or(false);
cx.notify();
});
}
@@ -407,12 +409,13 @@ impl OutlinePanel {
fn serialize(&mut self, cx: &mut ViewContext<Self>) {
let width = self.width;
let active = Some(self.active);
self.pending_serialization = cx.background_executor().spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
OUTLINE_PANEL_KEY.into(),
serde_json::to_string(&SerializedOutlinePanel { width })?,
serde_json::to_string(&SerializedOutlinePanel { width, active })?,
)
.await?;
anyhow::Ok(())
@@ -2522,7 +2525,7 @@ impl Panel for OutlinePanel {
}
fn starts_open(&self, _: &WindowContext) -> bool {
self.active_item.is_some()
self.active
}
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
@@ -2551,6 +2554,7 @@ impl Panel for OutlinePanel {
}
}
}
self.serialize(cx);
}
}

View File

@@ -317,11 +317,14 @@ impl Prettier {
})
.collect();
let prettier_parser = prettier_settings.parser.as_deref().or_else(|| buffer_language.and_then(|language| language.prettier_parser_name()));
let mut prettier_parser = prettier_settings.parser.as_deref();
if buffer_path.is_none() {
prettier_parser = prettier_parser.or_else(|| buffer_language.and_then(|language| language.prettier_parser_name()));
if prettier_parser.is_none() {
log::error!("Formatting unsaved file with prettier failed. No prettier parser configured for language {buffer_language:?}");
return Err(anyhow!("Cannot determine prettier parser for unsaved file"));
}
if prettier_parser.is_none() && buffer_path.is_none() {
log::error!("Formatting unsaved file with prettier failed. No prettier parser configured for language {buffer_language:?}");
return Err(anyhow!("Cannot determine prettier parser for unsaved file"));
}
log::debug!(

View File

@@ -8192,7 +8192,7 @@ impl Project {
}
};
if abs_path.ends_with(local_settings_file_relative_path()) {
if path.ends_with(local_settings_file_relative_path()) {
let settings_dir = Arc::from(
path.ancestors()
.nth(local_settings_file_relative_path().components().count())
@@ -8209,7 +8209,7 @@ impl Project {
},
)
});
} else if abs_path.ends_with(local_tasks_file_relative_path()) {
} else if path.ends_with(local_tasks_file_relative_path()) {
self.task_inventory().update(cx, |task_inventory, cx| {
if removed {
task_inventory.remove_local_static_source(&abs_path);
@@ -8229,7 +8229,7 @@ impl Project {
);
}
})
} else if abs_path.ends_with(local_vscode_tasks_file_relative_path()) {
} else if path.ends_with(local_vscode_tasks_file_relative_path()) {
self.task_inventory().update(cx, |task_inventory, cx| {
if removed {
task_inventory.remove_local_static_source(&abs_path);

View File

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

View File

@@ -1 +1 @@
dev
stable