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 // Include file content.
37 for chunk in buffer.text_for_range(0..range.start) {
38 prompt.push_str(chunk);
39 }
40
41 if range.is_empty() {
42 prompt.push_str("<|START|>");
43 } else {
44 prompt.push_str("<|START|");
45 }
46
47 for chunk in buffer.text_for_range(range.clone()) {
48 prompt.push_str(chunk);
49 }
50
51 if !range.is_empty() {
52 prompt.push_str("|END|>");
53 }
54
55 for chunk in buffer.text_for_range(range.end..buffer.len()) {
56 prompt.push_str(chunk);
57 }
58
59 prompt.push('\n');
60
61 if range.is_empty() {
62 writeln!(
63 prompt,
64 "Assume the cursor is located where the `<|START|>` span is."
65 )
66 .unwrap();
67 writeln!(
68 prompt,
69 "{content_type} can't be replaced, so assume your answer will be inserted at the cursor.",
70 )
71 .unwrap();
72 writeln!(
73 prompt,
74 "Generate {content_type} based on the users prompt: {user_prompt}",
75 )
76 .unwrap();
77 } else {
78 writeln!(prompt, "Modify the user's selected {content_type} based upon the users prompt: '{user_prompt}'").unwrap();
79 writeln!(prompt, "You must reply with only the adjusted {content_type} (within the '<|START|' and '|END|>' spans) not the entire file.").unwrap();
80 writeln!(
81 prompt,
82 "Double check that you only return code and not the '<|START|' and '|END|'> spans"
83 )
84 .unwrap();
85 }
86
87 writeln!(prompt, "Never make remarks about the output.").unwrap();
88 writeln!(
89 prompt,
90 "Do not return anything else, except the generated {content_type}."
91 )
92 .unwrap();
93
94 Ok(prompt)
95}