Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
saranshsaini committed Jan 30, 2025
1 parent ca4acb1 commit c6d1841
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 30 deletions.
42 changes: 13 additions & 29 deletions CodeiumVS/LanguageServer/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ async Task AddFilesToIndexLists(EnvDTE.Project project)
}
string projectFullName = project.FullName;
string projectName = Path.GetFileNameWithoutExtension(projectFullName);
IEnumerable<string> commonDirs;
if (!string.IsNullOrEmpty(projectFullName) && !processedProjects.Any(p => projectFullName.StartsWith(p)))
{
string projectDir = Path.GetDirectoryName(projectFullName);
Expand Down Expand Up @@ -857,25 +858,7 @@ async Task AddFilesToIndexLists(EnvDTE.Project project)
fullPaths.Add(fullPath);
}

if (fullPaths.Count > 0)
{
// Find the common root directory
string commonRoot = Path.GetDirectoryName(fullPaths[0]);
foreach (var path in fullPaths.Skip(1))
{
string directory = Path.GetDirectoryName(path);
while (!directory.StartsWith(commonRoot, StringComparison.OrdinalIgnoreCase) && commonRoot.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Where(s => !string.IsNullOrWhiteSpace(s)).Count() > 4)
{
commonRoot = Path.GetDirectoryName(commonRoot);
}
}

if (Directory.Exists(commonRoot))
{
await _package.LogAsync($"Common root directory: {commonRoot}");
projectCommonRoot = commonRoot;
}
}
commonDirs = FileUtilities.FindMinimumEncompassingDirectories(fullPaths);
}
catch (Exception ex)
{
Expand All @@ -888,26 +871,27 @@ async Task AddFilesToIndexLists(EnvDTE.Project project)
List<string> matchingFiles = new List<string>();
foreach (var filePath in openFilePaths)
{
if (filePath.StartsWith(projectCommonRoot, StringComparison.OrdinalIgnoreCase))
var matchingDir = commonDirs.FirstOrDefault(dir => filePath.StartsWith(dir, StringComparison.OrdinalIgnoreCase));
if (matchingDir != null)
{
await _package.LogAsync($"Found in open files {filePath}");
await _package.LogAsync($"Found in open files {filePath}, {matchingDir}");
openFilesProjectsToIndexPath.Add(matchingDir);
matchingFiles.Add(filePath);
}
}
if (matchingFiles.Count > 0)
if (matchingFiles.Any())
{
openFilesProjectsToIndexPath.Add(projectCommonRoot);
remainingToFind--;
foreach (var file in matchingFiles)
{
openFilePaths.Remove(file);
}
openFilePaths.ExceptWith(matchingFiles);
}
}
else
{
await _package.LogAsync($"Found in remaining {projectCommonRoot}");
remainingProjectsToIndexPath.Add(projectCommonRoot);
await _package.LogAsync($"Found in remaining {commondDirs.Count}");
foreach (var dir in commonDirs)
{
remainingProjectsToIndexPath.Add(dir);
}
}
processedProjects.Add(projectFullName);
}
Expand Down
65 changes: 64 additions & 1 deletion CodeiumVS/Utilities/FileUtilities.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace CodeiumVS.Utilities;

Expand Down Expand Up @@ -44,4 +47,64 @@ internal static void DeleteSafe(string path)
}
}
}

/// <summary>
/// Finds the minimum set of directories that encompass all the given files.
/// For example, given ["E:/a/b/c.txt", "E:/a/b/d/e.cpp"], returns ["E:/a/b"]
/// </summary>
/// <param name="filePaths">List of absolute file paths</param>
/// <returns>List of directory paths that collectively contain all input files with minimum redundancy</returns>
internal static List<string> FindMinimumEncompassingDirectories(IEnumerable<string> filePaths)
{
if (filePaths == null || !filePaths.Any())
return new List<string>();

// Get all parent directories for each file
var allPaths = filePaths.Select(path =>
{
var parents = new List<string>();
var dir = Path.GetDirectoryName(path);
while (!string.IsNullOrEmpty(dir))
{
parents.Add(dir);
dir = Path.GetDirectoryName(dir);
}
return parents;
}).ToList();

// Find directories that contain files
var directoryCounts = new Dictionary<string, HashSet<int>>();
for (int i = 0; i < allPaths.Count; i++)
{
foreach (var dir in allPaths[i])
{
if (!directoryCounts.ContainsKey(dir))
directoryCounts[dir] = new HashSet<int>();
directoryCounts[dir].Add(i);
}
}

var result = new List<string>();
var coveredFiles = new HashSet<int>();

// While we haven't covered all files
while (coveredFiles.Count < allPaths.Count)
{
// Find directory that covers most uncovered files
var bestDir = directoryCounts
.Where(kvp => kvp.Value.Except(coveredFiles).Any())
.OrderByDescending(kvp => kvp.Value.Except(coveredFiles).Count())
.ThenBy(kvp => kvp.Key.Count(c => c == Path.DirectorySeparatorChar)) // Prefer deeper directories
.FirstOrDefault();

if (bestDir.Key == null)
break;

result.Add(bestDir.Key);
coveredFiles.UnionWith(bestDir.Value);
}

// Filter out paths that are too shallow (less than 3 levels deep)
return result.Where(dir => dir.Count(c => c == Path.DirectorySeparatorChar) >= 2).ToList();
}
}

0 comments on commit c6d1841

Please sign in to comment.