/// <summary> /// Repositions the specified item into the specified base. /// </summary> /// <param name="itemToMove">The item to move.</param> /// <param name="baseItem">The base item.</param> private void RepositionItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem) { if (itemToMove == baseItem) { return; } bool padWithNewLine = _insertBlankLinePaddingLogic.ShouldBeFollowedByBlankLine(itemToMove); int cursorOffset; var text = GetTextAndRemoveItem(itemToMove, out cursorOffset); baseItem.RefreshCachedPositionAndName(); var baseInsertPoint = baseItem.InsertPoint; var pastePoint = baseInsertPoint.CreateEditPoint(); pastePoint.Insert(text); pastePoint.Insert(Environment.NewLine); if (padWithNewLine) { pastePoint.Insert(Environment.NewLine); } pastePoint.EndOfLine(); baseInsertPoint.SmartFormat(pastePoint); if (cursorOffset >= 0) { baseInsertPoint.Parent.Selection.MoveToAbsoluteOffset(baseInsertPoint.AbsoluteCharOffset + cursorOffset); } itemToMove.RefreshCachedPositionAndName(); baseItem.RefreshCachedPositionAndName(); }
/// <summary> /// Recursively reorganizes the specified code items. /// </summary> /// <param name="codeItems">The code items.</param> /// <param name="parent">The parent to the code items, otherwise null.</param> private void RecursivelyReorganize(IEnumerable <BaseCodeItem> codeItems, ICodeItemParent parent = null) { if (!codeItems.Any()) { // If there are no code items, the only action we may want to take is conditionally insert regions. RegionsInsert(codeItems, parent); return; } // Conditionally remove existing regions. codeItems = RegionsRemoveExisting(codeItems); // Conditionally ignore regions. codeItems = RegionsFlatten(codeItems); // Get the items in their current order and their desired order. var currentOrder = GetReorganizableCodeItemElements(codeItems); var desiredOrder = new List <BaseCodeItemElement>(currentOrder); desiredOrder.Sort(new CodeItemTypeComparer(Settings.Default.Reorganizing_AlphabetizeMembersOfTheSameGroup)); // Iterate across the items in the desired order, moving them when necessary. for (int desiredIndex = 0; desiredIndex < desiredOrder.Count; desiredIndex++) { var item = desiredOrder[desiredIndex]; var itemAsParent = item as ICodeItemParent; if (itemAsParent != null && ShouldReorganizeChildren(item)) { RecursivelyReorganize(itemAsParent.Children, itemAsParent); } int currentIndex = currentOrder.IndexOf(item); if (desiredIndex != currentIndex) { // Move the item above what is in its desired position. RepositionItemAboveBase(item, currentOrder[desiredIndex]); // Update the current order to match the move. currentOrder.RemoveAt(currentIndex); currentOrder.Insert(desiredIndex > currentIndex ? desiredIndex - 1 : desiredIndex, item); } } // Conditionally insert regions. RegionsInsert(codeItems, parent); // Recursively reorganize the contents of any regions as well. var codeItemRegions = codeItems.OfType <CodeItemRegion>(); foreach (var codeItemRegion in codeItemRegions) { RecursivelyReorganize(codeItemRegion.Children, codeItemRegion); } }
/// <summary> /// Conditionally inserts regions for the specified code items. /// </summary> /// <param name="codeItems">The code items.</param> /// <param name="parent">The parent to the code items, otherwise null.</param> private void RegionsInsert(IEnumerable <BaseCodeItem> codeItems, ICodeItemParent parent) { if (Settings.Default.Reorganizing_RegionsInsertNewRegions) { // Only insert regions when directly inside the scope of a class, interface or struct. if (parent is CodeItemClass || parent is CodeItemInterface || parent is CodeItemStruct) { _generateRegionLogic.InsertRegions(codeItems, parent.InsertPoint); } } }
/// <summary> /// Attempts to find a <see cref="ICollapsible" /> associated with the specified <see /// cref="ICodeItemParent" />. /// </summary> /// <param name="parent">The code item parent.</param> /// <returns>The <see cref="ICollapsible" /> on the same starting line, otherwise null.</returns> private ICollapsible FindCollapsibleFromCodeItemParent(ICodeItemParent parent) { if (_outliningManager == null || _wpfTextView == null) { return(null); } var snapshotLine = _wpfTextView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(parent.StartLine); var collapsibles = _outliningManager.GetAllRegions(snapshotLine.Extent); return((from collapsible in collapsibles let startLine = GetStartLineForCollapsible(collapsible) where startLine == parent.StartLine select collapsible).FirstOrDefault()); }
/// <summary> /// Recursively groups the children within the specified item based on their type. /// </summary> /// <param name="codeItem">The code item.</param> private static void RecursivelyGroupByType(ICodeItemParent codeItem) { // Skip any code item that is already a region or does not have children. if (codeItem.Kind == KindCodeItem.Region || !codeItem.Children.Any()) { return; } // Capture the current children, then clear them out so they can be re-added. var children = codeItem.Children.ToArray(); codeItem.Children.Clear(); CodeItemRegion group = null; int groupOrder = -1; foreach (var child in children) { var memberTypeSetting = MemberTypeSettingHelper.LookupByKind(child.Kind); // Create a new group unless the right kind has already been defined. if (group == null || memberTypeSetting.Order != groupOrder) { group = new CodeItemRegion { Name = memberTypeSetting.EffectiveName, IsPseudoGroup = true }; if (Settings.Default.Digging_TrackExpandedStateOfSpadeNodes) { group.IsExpanded = CodeItemRegionGlobals.GetIsExpandedFor(group.Name); } groupOrder = memberTypeSetting.Order; codeItem.Children.Add(group); } // Add the child to the group and recurse. group.Children.Add(child); var childAsParent = child as ICodeItemParent; if (childAsParent != null) { RecursivelyGroupByType(childAsParent); } } }
/// <summary> /// Recursively gets the children in a depth-first fashion for the specified parent without /// delving into nested element parents. /// </summary> /// <param name="parent">The parent.</param> /// <returns>The recursive set of children.</returns> public static SetCodeItems GetChildrenRecursive(this ICodeItemParent parent) { var children = new SetCodeItems(); foreach (var child in parent.Children) { children.Add(child); var childAsParent = child as ICodeItemParent; if (childAsParent != null && !(child is BaseCodeItemElementParent)) { children.AddRange(childAsParent.GetChildrenRecursive()); } } return(children); }
/// <summary> /// Attempts to find a <see cref="ICollapsible" /> associated with the specified <see /// cref="ICodeItemParent" />. /// </summary> /// <param name="parent">The code item parent.</param> /// <returns>The <see cref="ICollapsible" /> on the same starting line, otherwise null.</returns> private ICollapsible FindCollapsibleFromCodeItemParent(ICodeItemParent parent) { if (_outliningManager == null || _wpfTextView == null) { return(null); } try { var snapshotLine = _wpfTextView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(parent.StartLine); var collapsibles = _outliningManager.GetAllRegions(snapshotLine.Extent); return((from collapsible in collapsibles let startLine = GetStartLineForCollapsible(collapsible) where startLine == parent.StartLine select collapsible).FirstOrDefault()); } catch (Exception ex) { OutputWindowHelper.ExceptionWriteLine("Unable to find collapsible from ICodeItemParent", ex); return(null); } }
/// <summary> /// Repositions the specified item into the specified base. /// </summary> /// <param name="itemToMove">The item to move.</param> /// <param name="baseItem">The base item.</param> private void RepositionItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem) { if (itemToMove == baseItem) return; bool padWithNewLine = _insertBlankLinePaddingLogic.ShouldInstanceBeFollowedByBlankLine(itemToMove); int cursorOffset; var text = GetTextAndRemoveItem(itemToMove, out cursorOffset); baseItem.RefreshCachedPositionAndName(); var baseInsertPoint = baseItem.InsertPoint; var pastePoint = baseInsertPoint.CreateEditPoint(); pastePoint.Insert(text); pastePoint.Insert(Environment.NewLine); if (padWithNewLine) { pastePoint.Insert(Environment.NewLine); } pastePoint.EndOfLine(); baseInsertPoint.SmartFormat(pastePoint); if (cursorOffset >= 0) { baseInsertPoint.Parent.Selection.MoveToAbsoluteOffset(baseInsertPoint.AbsoluteCharOffset + cursorOffset); } itemToMove.RefreshCachedPositionAndName(); baseItem.RefreshCachedPositionAndName(); }
/// <summary> /// Conditionally inserts regions for the specified code items. /// </summary> /// <param name="codeItems">The code items.</param> /// <param name="parent">The parent to the code items, otherwise null.</param> private void RegionsInsert(IEnumerable<BaseCodeItem> codeItems, ICodeItemParent parent) { if (Settings.Default.Reorganizing_RegionsInsertNewRegions) { // Only insert regions when directly inside the scope of a class, interface or struct. if (parent is CodeItemClass || parent is CodeItemInterface || parent is CodeItemStruct) { _generateRegionLogic.InsertRegions(codeItems, parent.InsertPoint); } } }
/// <summary> /// Recursively reorganizes the specified code items. /// </summary> /// <param name="codeItems">The code items.</param> /// <param name="parent">The parent to the code items, otherwise null.</param> private void RecursivelyReorganize(IEnumerable<BaseCodeItem> codeItems, ICodeItemParent parent = null) { if (!codeItems.Any()) { // If there are no code items, the only action we may want to take is conditionally insert regions. RegionsInsert(codeItems, parent); return; } // Conditionally remove existing regions. codeItems = RegionsRemoveExisting(codeItems); // Conditionally ignore regions. codeItems = RegionsFlatten(codeItems); // Get the items in their current order and their desired order. var currentOrder = GetReorganizableCodeItemElements(codeItems); var desiredOrder = currentOrder.OrderBy(CodeItemTypeComparer.CalculateNumericRepresentation) .ThenBy(x => Settings.Default.Reorganizing_AlphabetizeMembersOfTheSameGroup ? (object)x.Name : (object)x.StartOffset) .ToList(); // Iterate across the items in the desired order, moving them when necessary. for (int desiredIndex = 0; desiredIndex < desiredOrder.Count; desiredIndex++) { var item = desiredOrder[desiredIndex]; var itemAsParent = item as ICodeItemParent; if (itemAsParent != null && ShouldReorganizeChildren(item)) { RecursivelyReorganize(itemAsParent.Children, itemAsParent); } int currentIndex = currentOrder.IndexOf(item); if (desiredIndex != currentIndex) { // Move the item above what is in its desired position. RepositionItemAboveBase(item, currentOrder[desiredIndex]); // Update the current order to match the move. currentOrder.RemoveAt(currentIndex); currentOrder.Insert(desiredIndex > currentIndex ? desiredIndex - 1 : desiredIndex, item); } } // Conditionally insert regions. RegionsInsert(codeItems, parent); // Recursively reorganize the contents of any regions as well. var codeItemRegions = codeItems.OfType<CodeItemRegion>(); foreach (var codeItemRegion in codeItemRegions) { RecursivelyReorganize(codeItemRegion.Children, codeItemRegion); } }
/// <summary> /// Moves the specified item into the specified base. /// </summary> /// <param name="itemToMove">The item to move.</param> /// <param name="baseItem">The base item.</param> internal void MoveItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem) { _undoTransactionHelper.Run(() => RepositionItemIntoBase(itemToMove, baseItem)); }
/// <summary> /// Recursively groups the children within the specified item based on their type. /// </summary> /// <param name="codeItem">The code item.</param> private static void RecursivelyGroupByType(ICodeItemParent codeItem) { // Skip any code item that is already a region or does not have children. if (codeItem.Kind == KindCodeItem.Region || !codeItem.Children.Any()) { return; } // Capture the current children, then clear them out so they can be re-added. var children = codeItem.Children.ToArray(); codeItem.Children.Clear(); CodeItemRegion group = null; int groupOrder = -1; foreach (var child in children) { var memberTypeSetting = MemberTypeSettingHelper.LookupByKind(child.Kind); // Create a new group unless the right kind has already been defined. if (group == null || memberTypeSetting.Order != groupOrder) { group = new CodeItemRegion { Name = memberTypeSetting.EffectiveName, IsPseudoGroup = true }; groupOrder = memberTypeSetting.Order; codeItem.Children.Add(group); } // Add the child to the group and recurse. group.Children.Add(child); var childAsParent = child as ICodeItemParent; if (childAsParent != null) { RecursivelyGroupByType(childAsParent); } } }
/// <summary> /// Moves the specified item into the specified base. /// </summary> /// <param name="itemToMove">The item to move.</param> /// <param name="baseItem">The base item.</param> internal void MoveItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem) { new UndoTransactionHelper(_package, "CodeMaid Move Item Into").Run( () => RepositionItemIntoBase(itemToMove, baseItem)); }
/// <summary> /// Attempts to find a <see cref="ICollapsible" /> associated with the specified <see /// cref="ICodeItemParent" />. /// </summary> /// <param name="parent">The code item parent.</param> /// <returns>The <see cref="ICollapsible" /> on the same starting line, otherwise null.</returns> private ICollapsible FindCollapsibleFromCodeItemParent(ICodeItemParent parent) { if (_outliningManager == null || _wpfTextView == null) { return null; } try { var snapshotLine = _wpfTextView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(parent.StartLine); var collapsibles = _outliningManager.GetAllRegions(snapshotLine.Extent); return (from collapsible in collapsibles let startLine = GetStartLineForCollapsible(collapsible) where startLine == parent.StartLine select collapsible).FirstOrDefault(); } catch (Exception ex) { OutputWindowHelper.ExceptionWriteLine("Unable to find collapsible from ICodeItemParent", ex); return null; } }
/// <summary> /// Attempts to find a <see cref="ICollapsible" /> associated with the specified <see /// cref="ICodeItemParent" />. /// </summary> /// <param name="parent">The code item parent.</param> /// <returns>The <see cref="ICollapsible" /> on the same starting line, otherwise null.</returns> private ICollapsible FindCollapsibleFromCodeItemParent(ICodeItemParent parent) { if (_outliningManager == null || _wpfTextView == null) { return null; } var snapshotLine = _wpfTextView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(parent.StartLine); var collapsibles = _outliningManager.GetAllRegions(snapshotLine.Extent); return (from collapsible in collapsibles let startLine = GetStartLineForCollapsible(collapsible) where startLine == parent.StartLine select collapsible).FirstOrDefault(); }