Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(codeSearch): normalize path for code search #3393

5 changes: 4 additions & 1 deletion crates/tabby-common/src/api/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::path::normalize_path;

pub struct CodeSearchResponse {
pub hits: Vec<CodeSearchHit>,
}
Expand Down Expand Up @@ -50,6 +52,7 @@ pub enum CodeSearchError {
}

pub struct CodeSearchQuery {
// filepath in code search query always normalize to unix style.
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
pub filepath: Option<String>,
pub language: Option<String>,
pub content: String,
Expand All @@ -64,7 +67,7 @@ impl CodeSearchQuery {
source_id: String,
) -> Self {
Self {
filepath,
filepath: normalize_path(filepath).unwrap_or(None),
language,
content,
source_id,
Expand Down
67 changes: 67 additions & 0 deletions crates/tabby-common/src/path.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{cell::Cell, env, path::PathBuf, sync::Mutex};

use anyhow::Result;
use lazy_static::lazy_static;

lazy_static! {
Expand Down Expand Up @@ -53,4 +54,70 @@ pub fn events_dir() -> PathBuf {
tabby_root().join("events")
}

fn normalize_path_for_platform(
filepath: Option<String>,
is_windows: bool,
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<Option<String>> {
Ok(filepath.clone().map(|path| {
let path_buf = PathBuf::from(path);
if is_windows {
path_buf.to_string_lossy().replace('/', "\\")
} else {
path_buf.to_string_lossy().replace('\\', "/")
}
}))
}

/// Normalize the path to unix style path
pub fn normalize_path(filepath: Option<String>) -> Result<Option<String>> {
#[cfg(target_os = "windows")]
return normalize_path_for_platform(filepath, true);

#[cfg(not(target_os = "windows"))]
return normalize_path_for_platform(filepath, false);
}

mod registry {}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_relative_path_normalization() {
// the most common use, converting relative path to unix style
assert_eq!(
normalize_path_for_platform(Some("./src/main.rs".to_string()), false).unwrap(),
Some("./src/main.rs".to_string())
);
assert_eq!(
normalize_path_for_platform(Some(".\\src\\main.rs".to_string()), false).unwrap(),
Some("./src/main.rs".to_string())
);
assert_eq!(
normalize_path_for_platform(Some("../test/data.json".to_string()), false).unwrap(),
Some("../test/data.json".to_string())
);
assert_eq!(
normalize_path_for_platform(Some("..\\test\\data.json".to_string()), false).unwrap(),
Some("../test/data.json".to_string())
);

assert_eq!(
normalize_path_for_platform(Some("./src/main.rs".to_string()), true).unwrap(),
Some(".\\src\\main.rs".to_string())
);
assert_eq!(
normalize_path_for_platform(Some(".\\src\\main.rs".to_string()), true).unwrap(),
Some(".\\src\\main.rs".to_string())
);
assert_eq!(
normalize_path_for_platform(Some("../test/data.json".to_string()), true).unwrap(),
Some("..\\test\\data.json".to_string())
);
assert_eq!(
normalize_path_for_platform(Some("..\\test\\data.json".to_string()), true).unwrap(),
Some("..\\test\\data.json".to_string())
);
}
}
1 change: 1 addition & 0 deletions crates/tabby/src/services/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub struct Segments {
suffix: Option<String>,

/// The relative path of the file that is being edited.
/// The filepath will keep the same format as the original file path base on the platform.
Sma1lboy marked this conversation as resolved.
Show resolved Hide resolved
/// - When [Segments::git_url] is set, this is the path of the file in the git repository.
/// - When [Segments::git_url] is empty, this is the path of the file in the workspace.
filepath: Option<String>,
Expand Down
Loading