prompts.rs

  1use language::BufferSnapshot;
  2use std::{fmt::Write, ops::Range};
  3
  4pub fn generate_content_prompt(
  5    user_prompt: String,
  6    language_name: Option<&str>,
  7    buffer: BufferSnapshot,
  8    range: Range<usize>,
  9    project_name: Option<String>,
 10) -> anyhow::Result<String> {
 11    let mut prompt = String::new();
 12
 13    let content_type = match language_name {
 14        None | Some("Markdown" | "Plain Text") => {
 15            writeln!(prompt, "You are an expert engineer.")?;
 16            "Text"
 17        }
 18        Some(language_name) => {
 19            writeln!(prompt, "You are an expert {language_name} engineer.")?;
 20            writeln!(
 21                prompt,
 22                "Your answer MUST always and only be valid {}.",
 23                language_name
 24            )?;
 25            "Code"
 26        }
 27    };
 28
 29    if let Some(project_name) = project_name {
 30        writeln!(
 31            prompt,
 32            "You are currently working inside the '{project_name}' project in code editor Zed."
 33        )?;
 34    }
 35
 36    writeln!(
 37        prompt,
 38        "The user has the following file open in the editor:"
 39    )?;
 40    if range.is_empty() {
 41        write!(prompt, "```")?;
 42        if let Some(language_name) = language_name {
 43            write!(prompt, "{language_name}")?;
 44        }
 45
 46        for chunk in buffer.as_rope().chunks_in_range(0..range.start) {
 47            prompt.push_str(chunk);
 48        }
 49        prompt.push_str("<|CURSOR|>");
 50        for chunk in buffer.as_rope().chunks_in_range(range.start..buffer.len()) {
 51            prompt.push_str(chunk);
 52        }
 53        if !prompt.ends_with('\n') {
 54            prompt.push('\n');
 55        }
 56        writeln!(prompt, "```")?;
 57        prompt.push('\n');
 58
 59        writeln!(
 60            prompt,
 61            "Assume the cursor is located where the `<|CURSOR|>` span is."
 62        )
 63        .unwrap();
 64        writeln!(
 65            prompt,
 66            "{content_type} can't be replaced, so assume your answer will be inserted at the cursor.",
 67        )
 68        .unwrap();
 69        writeln!(
 70            prompt,
 71            "Generate {content_type} based on the users prompt: {user_prompt}",
 72        )
 73        .unwrap();
 74    } else {
 75        write!(prompt, "```")?;
 76        for chunk in buffer.as_rope().chunks() {
 77            prompt.push_str(chunk);
 78        }
 79        if !prompt.ends_with('\n') {
 80            prompt.push('\n');
 81        }
 82        writeln!(prompt, "```")?;
 83        prompt.push('\n');
 84
 85        writeln!(
 86            prompt,
 87            "In particular, the following piece of text is selected:"
 88        )?;
 89        write!(prompt, "```")?;
 90        if let Some(language_name) = language_name {
 91            write!(prompt, "{language_name}")?;
 92        }
 93        prompt.push('\n');
 94        for chunk in buffer.text_for_range(range.clone()) {
 95            prompt.push_str(chunk);
 96        }
 97        if !prompt.ends_with('\n') {
 98            prompt.push('\n');
 99        }
100        writeln!(prompt, "```")?;
101        prompt.push('\n');
102
103        writeln!(
104            prompt,
105            "Modify the user's selected {content_type} based upon the users prompt: {user_prompt}"
106        )
107        .unwrap();
108        writeln!(
109            prompt,
110            "You must reply with only the adjusted {content_type}, not the entire file."
111        )
112        .unwrap();
113    }
114
115    writeln!(prompt, "Never make remarks about the output.").unwrap();
116    writeln!(
117        prompt,
118        "Do not return anything else, except the generated {content_type}."
119    )
120    .unwrap();
121
122    Ok(prompt)
123}