Example #1
0
        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);
                }
            }
        }