diff --git a/crates/edit_prediction/src/zeta2.rs b/crates/edit_prediction/src/zeta2.rs index 882e000204c01a394c2e401b8c0c885926f26cb8..3be486bae5cdd64510bbb6eb73f9f06632c88bda 100644 --- a/crates/edit_prediction/src/zeta2.rs +++ b/crates/edit_prediction/src/zeta2.rs @@ -285,7 +285,23 @@ pub fn zeta2_output_for_patch(input: &zeta_prompt::ZetaPromptInput, patch: &str) let old_prefix = &text[..editable_region.start]; let old_suffix = &text[editable_region.end..]; - let new = crate::udiff::apply_diff_to_string(patch, text)?; + // Try applying the patch directly first + let new = match crate::udiff::apply_diff_to_string(patch, text) { + Ok(new) => new, + Err(_) if !text.ends_with('\n') => { + // If the text doesn't end with a newline, the patch context may expect one + // (due to missing "no newline at EOF" markers). Try again with a trailing newline. + let text_with_newline = format!("{}\n", text); + let mut new = crate::udiff::apply_diff_to_string(patch, &text_with_newline)?; + // Remove the trailing newline we added if the result still has it + if new.ends_with('\n') && !text.ends_with('\n') { + new.pop(); + } + new + } + Err(e) => return Err(e), + }; + if !new.starts_with(old_prefix) || !new.ends_with(old_suffix) { anyhow::bail!("Patch shouldn't affect text outside of editable region"); }