Skip to content

Commit d39eae3

Browse files
committed
Handle subdirectories also
1 parent 5b3c7b4 commit d39eae3

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

crates/shell/src/completion.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,18 @@ fn is_executable(entry: &fs::DirEntry) -> bool {
187187
}
188188

189189
fn resolve_dir_path(dir_path: &str) -> PathBuf {
190+
// Unescape the directory path to handle spaces and other special characters
191+
let unescaped = unescape_for_completion(dir_path);
192+
190193
if dir_path.starts_with('/') {
191-
PathBuf::from(dir_path)
194+
PathBuf::from(unescaped)
192195
} else if let Some(stripped) = dir_path.strip_prefix('~') {
196+
let unescaped_stripped = unescape_for_completion(stripped);
193197
dirs::home_dir()
194-
.map(|h| h.join(stripped.strip_prefix('/').unwrap_or(stripped)))
195-
.unwrap_or_else(|| PathBuf::from(dir_path))
198+
.map(|h| h.join(unescaped_stripped.strip_prefix('/').unwrap_or(&unescaped_stripped)))
199+
.unwrap_or_else(|| PathBuf::from(unescaped))
196200
} else {
197-
PathBuf::from(".").join(dir_path)
201+
PathBuf::from(".").join(unescaped)
198202
}
199203
}
200204

@@ -465,4 +469,50 @@ mod tests {
465469
.unwrap();
466470
assert_eq!(matches.len(), 0);
467471
}
472+
473+
#[tokio::test]
474+
async fn test_complete_files_in_directory_with_spaces() {
475+
let temp_dir = TempDir::new().unwrap();
476+
let temp_path = temp_dir.path();
477+
478+
// Create a directory with a space in its name
479+
fs::create_dir(temp_path.join("some dir")).unwrap();
480+
fs::File::create(temp_path.join("some dir/file1.txt")).unwrap();
481+
fs::File::create(temp_path.join("some dir/file2.txt")).unwrap();
482+
483+
let completer = ShellCompleter::new(HashSet::new());
484+
let history = DefaultHistory::new();
485+
486+
// Test 1: completion of "some\ d" should suggest the directory
487+
let line = format!("cd {}/some\\ d", temp_path.display());
488+
let pos = line.len();
489+
let (_start, matches) = completer
490+
.complete(&line, pos, &Context::new(&history))
491+
.unwrap();
492+
assert_eq!(matches.len(), 1);
493+
assert_eq!(
494+
matches[0].replacement,
495+
format!("{}/some\\ dir/", temp_path.display())
496+
);
497+
498+
// Test 2: completion of "some\ dir/f" should suggest both files
499+
let line = format!("cat {}/some\\ dir/f", temp_path.display());
500+
let pos = line.len();
501+
let (_start, matches) = completer
502+
.complete(&line, pos, &Context::new(&history))
503+
.unwrap();
504+
assert_eq!(matches.len(), 2);
505+
506+
// Test 3: completion of "some\ dir/file1" should complete to file1.txt
507+
let line = format!("cat {}/some\\ dir/file1", temp_path.display());
508+
let pos = line.len();
509+
let (_start, matches) = completer
510+
.complete(&line, pos, &Context::new(&history))
511+
.unwrap();
512+
assert_eq!(matches.len(), 1);
513+
assert_eq!(
514+
matches[0].replacement,
515+
format!("{}/some\\ dir/file1.txt", temp_path.display())
516+
);
517+
}
468518
}

0 commit comments

Comments
 (0)