Skip to content

Conversation

@CLoaKY233
Copy link

@CLoaKY233 CLoaKY233 commented Nov 4, 2025

🐛 Fix: Files not loading and incorrect directory paths in /file slash command

Summary

Fixed two critical bugs in the /file slash command that prevented proper file collection and displayed incorrect directory paths when using folders with the AI assistant panel.

Fixes: #41242

Problem Statement

Issue 1: Files Not Loading on Windows with /file [folder]

When using /file [folder] on Windows, files were not appearing under the specified folder. This was due to a path separator mismatch:

  • Windows uses backslashes: \\
  • Path matching expects forward slashes: /

Result:

❌ Files not loaded when running: /file Axum-Backend\crates
✅ Works when: /file Axum-Backend/crates

This made the feature unusable on Windows for nested folders.

Issue 2: Folded Directory Paths Leak to Siblings

When a directory contains a single-child chain (e.g., .github/workflows/), the folded path was not being reset after use. This caused the folded path to leak into subsequent sibling directories, resulting in:

❌ Incorrect: .github/crates
✅ Expected: Axum-Backend/crates or crates

❌ Incorrect: .github/src  
✅ Expected: Axum-Backend/src or src

Affected structure:

Axum-Backend/
├── .github/
│   └── workflows/        (foldable: single child)
│       └── ci.yml
├── crates/               (NOT foldable: multiple children)
│   ├── core/
│   └── utils/
└── src/
    └── main.rs

Root Cause

  1. Windows path separator issue: The glob matcher receives backslashes from Windows file paths but expects forward slashes. The path matching fails silently, causing the matcher to skip all files in that path.

  2. Folded path leak: The folded_directory_names variable accumulated folded paths but was never reset after outputting a folded directory. When the next sibling was processed, the check if folded_directory_names.is_empty() failed because it still contained the previous fold, causing incorrect label generation.

  3. Top-level label detection: Using filename.is_empty() doesn't reliably identify the top-level matched directory. The is_top_level_directory flag is more accurate.

Changes Made

Change 1: Normalize Windows backslashes to forward slashes in glob inputs

// BEFORE - In FileSlashCommand::run()
Task::ready(Ok(collect_files(
    workspace.read(cx).project().clone(),
    arguments,  // ❌ May contain backslashes on Windows
    cx,
).boxed()))

// AFTER - In FileSlashCommand::run()
let normalized_arguments: Vec<String> = arguments
    .iter()
    .map(|arg| arg.replace('\\', "/"))
    .collect();

Task::ready(Ok(collect_files(
    workspace.read(cx).project().clone(),
    &normalized_arguments,  // ✅ Always uses forward slashes
    cx,
).boxed()))

Change 2: Reset folded paths after use

// BEFORE
} else {
    let entry_name = folded_directory_names.join(RelPath::unix(&filename).unwrap());
    let entry_name = entry_name.display(path_style);
    events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
        icon: IconName::Folder,
        label: entry_name.to_string().into(),
        metadata: None,
    }))?;
    events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
        SlashCommandContent::Text {
            text: entry_name.to_string(),
            run_commands_in_text: false,
        },
    )))?;
    directory_stack.push(entry.path.clone());
    // ❌ folded_directory_names was NOT reset here!
}

// AFTER
} else {
    let entry_name = folded_directory_names.join(RelPath::unix(&filename).unwrap());
    let entry_name = entry_name.display(path_style);
    events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
        icon: IconName::Folder,
        label: entry_name.to_string().into(),
        metadata: None,
    }))?;
    events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
        SlashCommandContent::Text {
            text: entry_name.to_string(),
            run_commands_in_text: false,
        },
    )))?;
    directory_stack.push(entry.path.clone());
    folded_directory_names = RelPath::empty().into(); // ✅ Reset immediately after use
}

Change 3: Use is_top_level_directory flag for correct label detection

// BEFORE
let label = if filename.is_empty() {
    path_including_worktree_name.display(path_style).to_string()
} else {
    filename
};

// AFTER
let label = if is_top_level_directory {
    path_including_worktree_name.display(path_style).to_string()
} else {
    filename.clone()
};
if is_top_level_directory {
    is_top_level_directory = false;
}

Change 4: Simplify top-level folding accumulation logic

// BEFORE
if is_top_level_directory {
    is_top_level_directory = false;
    folded_directory_names = folded_directory_names.join(&path_including_worktree_name);
} else {
    folded_directory_names = folded_directory_names.join(RelPath::unix(&filename).unwrap());
}

// AFTER
if is_top_level_directory {
    is_top_level_directory = false;
    folded_directory_names = folded_directory_names.join(&path_including_worktree_name);
} else {
    folded_directory_names = RelPath::empty().into(); // Reset instead of accumulating
}

Before & After

Before (Windows):

❌ /file Axum-Backend\crates → No files loaded
❌ Path display: .github\crates (instead of Axum-Backend\crates)
❌ Path display: .github\src (instead of Axum-Backend\src)

After (Windows & All Platforms):

✅ /file Axum-Backend\crates → All files loaded correctly
✅ /file Axum-Backend/crates → All files loaded correctly
✅ Path display: Axum-Backend/crates
✅ Path display: Axum-Backend/src
✅ Path display: .github/workflows (folded correctly)

Checklist

  • Tests pass locally
  • Handles edge cases (empty directories, deeply nested structures, single-child chains)
  • Path normalization works for all path separators

Related Issue: #41242

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Nov 4, 2025
@SomeoneToIgnore SomeoneToIgnore added the ai Improvement related to Agent Panel, Edit Prediction, Copilot, or other AI features label Nov 4, 2025
@CLoaKY233 CLoaKY233 marked this pull request as ready for review November 4, 2025 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Improvement related to Agent Panel, Edit Prediction, Copilot, or other AI features cla-signed The user has signed the Contributor License Agreement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants