Repository: TabbyML/tabby
File: crates/tabby/src/services/completion.rs (Rust)

Code before:
    if segments.prefix.contains("\r\n") {
        return true;
    }
    if let Some(suffix) = &segments.suffix {
        if suffix.contains("\r\n") {
            return true;
        }
    }

    false
}

fn override_prompt(prompt: String, use_crlf: bool) -> String {
    if use_crlf {
        prompt.replace("\r\n", "\n")
    } else {
        prompt
    }
}

/// override_generated replaces \n with \r\n in the generated text if use_crlf is true.
/// This is used to ensure that the generated text has the same line endings as the prompt.
///
/// Because there might be \r\n in the text, which also has a `\n` and should not be replaced,
/// we can not simply replace \n with \r\n.
fn override_generated(generated: String, use_crlf: bool) -> String {
    if use_crlf {
        let re = Regex::new(r"([^\r])\n").unwrap(); // Match \n that is preceded by anything except \r
        re.replace_all(&generated, "$1\r\n").to_string() // Replace with captured character and \r\n
    } else {
        generated
    }
}

pub async fn create_completion_service_and_chat(
    config: &CompletionConfig,
    code: Arc<dyn CodeSearch>,
    logger: Arc<dyn EventLogger>,
    completion: Option<ModelConfig>,
    chat: Option<ModelConfig>,
) -> (
    Option<CompletionService>,
    Option<Arc<dyn ChatCompletionStream>>,
) {
    let (code_generation, prompt, chat) =
        model::load_code_generation_and_chat(completion, chat).await;

    let completion = code_generation.map(|code_generation| {
        CompletionService::new(
            config.to_owned(),
            code_generation.clone(),

Review comment (suggestion):
```suggestion
fn override_generated_text(generated_text: String, use_crlf: bool) -> String {
```

Code after:
fn contains_crlf(segments: &Segments) -> bool {
    if segments.prefix.contains("\r\n") {
        return true;
    }
    if let Some(suffix) = &segments.suffix {
        if suffix.contains("\r\n") {
            return true;
        }
    }

    false
}

fn override_prompt(prompt: String, use_crlf: bool) -> String {
    if use_crlf {
        prompt.replace("\r\n", "\n")
    } else {
        prompt
    }
}

/// override_generated_text replaces \n with \r\n in the generated text if use_crlf is true.
/// This is used to ensure that the generated text has the same line endings as the prompt.
///
/// Because there might be \r\n in the text, which also has a `\n` and should not be replaced,
/// we can not simply replace \n with \r\n.
fn override_generated_text(generated: String, use_crlf: bool) -> String {
    if use_crlf {
        let re = Regex::new(r"([^\r])\n").unwrap(); // Match \n that is preceded by anything except \r
        re.replace_all(&generated, "$1\r\n").to_string() // Replace with captured character and \r\n
    } else {
        generated
    }
}

pub async fn create_completion_service_and_chat(
    config: &CompletionConfig,
    code: Arc<dyn CodeSearch>,
    logger: Arc<dyn EventLogger>,
    completion: Option<ModelConfig>,
    chat: Option<ModelConfig>,
) -> (
    Option<CompletionService>,
    Option<Arc<dyn ChatCompletionStream>>,
) {
    let (code_generation, prompt, chat) =
        model::load_code_generation_and_chat(completion, chat).await;

    let completion = code_generation.map(|code_generation| {
        CompletionService::new(
            config.to_owned(),