private IEnumerable <ItemInfo> EnumDirectory(string path, string project, TinyList <string> logicalPath) { logicalPath = logicalPath.Cons(Path.GetFileName(path)); foreach (var f in Directory.GetFiles(path)) { var name = Path.GetFileName(f); yield return(new ItemInfo { Name = name, Path = f, ProjectName = project, IconIndex = IconCache.AddFile(f), LogicalPath = logicalPath.Foldr(new StringBuilder(), (s, b) => b.Append('/').Append(s)).Append('/').Append(name).ToString(), }); } foreach (var item in Directory.GetDirectories(path).Where(d => !SkipItem(Path.GetFileName(path))) .SelectMany(d => EnumDirectory(d, project, logicalPath))) { yield return(item); } }
private IEnumerable <ItemInfo> EnumHierarchyItems(IVsHierarchy hierarchy, uint itemId, int level, string project, TinyList <string> logicalPath) { var currentName = hierarchy.GetProp <string>(itemId, __VSHPROPID.VSHPROPID_Name); // Enumerate nested var nested = hierarchy.GetNested(itemId); if (nested != null) { if (level == 1) { project = currentName; } foreach (var item in EnumHierarchyItems(nested.Item1, nested.Item2, level, project, logicalPath)) { yield return(item); } yield break; } if (SkipItem(currentName)) { yield break; } yield return(new ItemInfo { Name = currentName, ProjectName = project, IconIndex = IconCache.Add(hierarchy, itemId), LogicalPath = logicalPath.Foldr(new StringBuilder(), (s, b) => b.Append('/') .Append(s)).Append('/').Append(currentName).ToString(), Path = (level > 0 && itemId != VSConstants.VSITEMID_NIL && itemId != VSConstants.VSITEMID_ROOT) ? hierarchy.GetCanonicalName(itemId) : null, }); // Enumerate normal children var hasSideEffects = hierarchy.GetProp <object>(itemId, __VSHPROPID.VSHPROPID_HasEnumerationSideEffects); if (hasSideEffects as bool? == true) { // Enumerate slow var path = hierarchy.GetCanonicalName(itemId).TrimEnd('/', '\\'); if (Directory.Exists(path)) { if (!SkipItem(currentName)) { foreach (var item in EnumDirectory(path, project, logicalPath)) { yield return(item); } } } else { // TODO: notify user somehow } } else { // Enumerate fast // maybe use __VSHPROPID.VSHPROPID_FirstVisibleChild ? var node = hierarchy.GetProp <object>(itemId, __VSHPROPID.VSHPROPID_FirstChild); if (level > 1) { logicalPath = logicalPath.Cons(currentName); } while (node != null) { var nodeId = (uint)(int)node; if (nodeId == VSConstants.VSITEMID_NIL) { break; } foreach (var item in EnumHierarchyItems(hierarchy, nodeId, level + 1, project, logicalPath)) { yield return(item); } node = hierarchy.GetProp <object>(nodeId, __VSHPROPID.VSHPROPID_NextSibling); } } }