Пример #1
0
        /// <summary>
        /// Composes a region based on the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>A region.</returns>
        private CodeItemRegion ComposeRegionForCodeItem(BaseCodeItem codeItem)
        {
            if (codeItem == null)
            {
                return(null);
            }

            var setting = MemberTypeSettingHelper.LookupByKind(codeItem.Kind);

            if (setting == null)
            {
                return(null);
            }

            var regionName = string.Empty;

            if (Settings.Default.Reorganizing_RegionsIncludeAccessLevel)
            {
                var element = codeItem as BaseCodeItemElement;
                if (element != null && (!Settings.Default.Reorganizing_RegionsIncludeAccessLevelForMethodsOnly || element is CodeItemMethod))
                {
                    var accessModifier = CodeElementHelper.GetAccessModifierKeyword(element.Access);
                    if (accessModifier != null)
                    {
                        regionName = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(accessModifier) + " ";
                    }
                }
            }

            regionName += setting.EffectiveName;

            return(new CodeItemRegion {
                Name = regionName
            });
        }
Пример #2
0
        /// <summary>
        /// Gets the text and removes the specified item.
        /// </summary>
        /// <param name="itemToRemove">The item to remove.</param>
        /// <param name="cursorOffset">
        /// The cursor's offset within the item being removed, otherwise -1.
        /// </param>
        private static string GetTextAndRemoveItem(BaseCodeItem itemToRemove, out int cursorOffset)
        {
            // Refresh the code item and capture its end points.
            itemToRemove.RefreshCachedPositionAndName();
            var removeStartPoint = itemToRemove.StartPoint;
            var removeEndPoint   = itemToRemove.EndPoint;

            // Determine the cursor's offset if within the item being removed.
            var cursorAbsoluteOffset = removeStartPoint.Parent.Selection.ActivePoint.AbsoluteCharOffset;

            if (cursorAbsoluteOffset >= removeStartPoint.AbsoluteCharOffset && cursorAbsoluteOffset <= removeEndPoint.AbsoluteCharOffset)
            {
                cursorOffset = cursorAbsoluteOffset - removeStartPoint.AbsoluteCharOffset;
            }
            else
            {
                cursorOffset = -1;
            }

            // Capture the text.
            var text = removeStartPoint.GetText(removeEndPoint);

            // Remove the text and cleanup whitespace.
            removeStartPoint.Delete(removeEndPoint);
            removeStartPoint.DeleteWhitespace(vsWhitespaceOptions.vsWhitespaceOptionsVertical);

            return(text);
        }
Пример #3
0
        /// <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();
        }
Пример #4
0
        /// <summary>
        /// Repositions the specified item above the specified base.
        /// </summary>
        /// <param name="itemToMove">The item to move.</param>
        /// <param name="baseItem">The base item.</param>
        private void RepositionItemAboveBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
        {
            if (itemToMove == baseItem)
            {
                return;
            }

            bool separateWithNewLine = ShouldBeSeparatedByNewLine(itemToMove, baseItem);
            int  cursorOffset;
            var  text = GetTextAndRemoveItem(itemToMove, out cursorOffset);

            baseItem.RefreshCachedPositionAndName();
            var baseStartPoint = baseItem.StartPoint;
            var pastePoint     = baseStartPoint.CreateEditPoint();

            pastePoint.Insert(text);
            pastePoint.Insert(Environment.NewLine);
            if (separateWithNewLine)
            {
                pastePoint.Insert(Environment.NewLine);
            }

            pastePoint.EndOfLine();
            baseStartPoint.SmartFormat(pastePoint);

            if (cursorOffset >= 0)
            {
                baseStartPoint.Parent.Selection.MoveToAbsoluteOffset(baseStartPoint.AbsoluteCharOffset + cursorOffset);
            }

            itemToMove.RefreshCachedPositionAndName();
            baseItem.RefreshCachedPositionAndName();
        }
Пример #5
0
        /// <summary>
        /// Attempts to select the text of the specified code item.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="codeItem">The code item.</param>
        internal static void SelectCodeItem(Document document, BaseCodeItem codeItem)
        {
            var textDocument = document.GetTextDocument();

            if (textDocument == null)
            {
                return;
            }

            try
            {
                codeItem.RefreshCachedPositionAndName();
                textDocument.Selection.MoveToPoint(codeItem.StartPoint, false);
                textDocument.Selection.MoveToPoint(codeItem.EndPoint, true);

                textDocument.Selection.SwapAnchor();
            }
            catch (Exception)
            {
                // Select operation may fail if element is no longer available.
            }
            finally
            {
                // Always set focus within the code editor window.
                document.Activate();
            }
        }
Пример #6
0
        /// <summary>
        /// Determines if the specified code item instance should be preceded by a blank line.
        /// Defaults to false for unknown kinds or null objects.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>True if code item should be preceded by a blank line, otherwise false.</returns>
        internal bool ShouldBePrecededByBlankLine(BaseCodeItem codeItem)
        {
            if (codeItem == null)
            {
                return(false);
            }

            switch (codeItem.Kind)
            {
            case KindCodeItem.Class:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeClasses);

            case KindCodeItem.Delegate:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeDelegates);

            case KindCodeItem.Enum:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeEnumerations);

            case KindCodeItem.Event:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeEvents);

            case KindCodeItem.Field:
                return(codeItem.IsMultiLine
                        ? Settings.Default.Cleaning_InsertBlankLinePaddingBeforeFieldsMultiLine
                        : Settings.Default.Cleaning_InsertBlankLinePaddingBeforeFieldsSingleLine);

            case KindCodeItem.Interface:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeInterfaces);

            case KindCodeItem.Namespace:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeNamespaces);

            case KindCodeItem.Constructor:
            case KindCodeItem.Destructor:
            case KindCodeItem.Method:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeMethods);

            case KindCodeItem.Indexer:
            case KindCodeItem.Property:
                return(codeItem.IsMultiLine
                        ? Settings.Default.Cleaning_InsertBlankLinePaddingBeforePropertiesMultiLine
                        : Settings.Default.Cleaning_InsertBlankLinePaddingBeforePropertiesSingleLine);

            case KindCodeItem.Region:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeRegionTags);

            case KindCodeItem.Struct:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeStructs);

            case KindCodeItem.Using:
                return(Settings.Default.Cleaning_InsertBlankLinePaddingBeforeUsingStatementBlocks);

            default:
                return(false);
            }
        }
Пример #7
0
        public void ShouldSortByGroupType()
        {
            BaseCodeItem method   = Create <CodeItemMethod>("a", 1);
            BaseCodeItem field    = Create <CodeItemField>("z", 2);
            var          comparer = new CodeItemTypeComparer(sortByName: true);

            int result = comparer.Compare(field, method);

            Assert.IsTrue(result < 0);
        }
Пример #8
0
        public void ShouldSortItemsOfTheSameTypeByOffset()
        {
            BaseCodeItem itemB    = Create <CodeItemField>("b", 1);
            BaseCodeItem itemA    = Create <CodeItemField>("a", 2);
            var          comparer = new CodeItemTypeComparer(sortByName: false);

            int result = comparer.Compare(itemA, itemB);

            Assert.IsTrue(result > 0);
        }
Пример #9
0
        public void ShouldPlaceExplicitInterfaceMembersAtTheEndOfTheGroup()
        {
            CodeItemMethod methodA  = CreateExplicitMethod("Interface", "A", 1);
            BaseCodeItem   methodB  = Create <CodeItemMethod>("B", 2);
            var            comparer = new CodeItemTypeComparer(sortByName: true);

            Settings.Default.Reorganizing_ExplicitMembersAtEnd = true;
            int result = comparer.Compare(methodB, methodA);

            Assert.IsTrue(result < 0);
        }
Пример #10
0
        public void ShouldSortByExplicitInterfaceMemberName()
        {
            CodeItemMethod methodZ  = CreateExplicitMethod("Interface", "Z", 1);
            BaseCodeItem   methodX  = Create <CodeItemMethod>("X", 2);
            var            comparer = new CodeItemTypeComparer(sortByName: true);

            Settings.Default.Reorganizing_ExplicitMembersAtEnd = false;
            int result = comparer.Compare(methodX, methodZ);

            Assert.IsTrue(result < 0);
        }
Пример #11
0
        /// <summary>
        /// Selects the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        private void SelectCodeItem(BaseCodeItem codeItem)
        {
            var viewModel = ViewModel;

            if (codeItem == null || viewModel == null || codeItem.StartOffset <= 0)
            {
                return;
            }

            Dispatcher.BeginInvoke(
                new Action(() => TextDocumentHelper.SelectCodeItem(viewModel.Document, codeItem)));
        }
Пример #12
0
        /// <summary>
        /// Jumps to the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        private void JumpToCodeItem(BaseCodeItem codeItem)
        {
            var viewModel = ViewModel;

            if (codeItem == null || viewModel == null || codeItem.StartOffset <= 0)
            {
                return;
            }

            Dispatcher.BeginInvoke(
                new Action(() => TextDocumentHelper.MoveToCodeItem(viewModel.Document, codeItem, Settings.Default.Digging_CenterOnWhole)));
        }
Пример #13
0
        /// <summary>
        /// Determines if the specified item is an ancestor of the specified base.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="baseItem">The base item.</param>
        /// <returns>True if item is an ancestor of the specified base, otherwise false.</returns>
        private static bool IsItemAncestorOfBase(BaseCodeItem item, BaseCodeItem baseItem)
        {
            var itemAsParent = item as ICodeItemParent;

            if (itemAsParent == null)
            {
                return(false);
            }

            return(itemAsParent.Children.Contains(baseItem) ||
                   itemAsParent.Children.Any(x => IsItemAncestorOfBase(x, baseItem)));
        }
Пример #14
0
        /// <summary>
        /// Attempts to build an image URI from the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>The built URI, otherwise null.</returns>
        private string BuildImageURIString(BaseCodeItem codeItem)
        {
            string typeComponent   = GetTypeComponentString(codeItem);
            string accessComponent = GetAccessString(codeItem as BaseCodeItemElement);

            if (typeComponent == null)
            {
                return(null);
            }

            string uriString = $"/Waodng.CodeMaid;component/UI/ToolWindows/Spade/Images/{ImagePath}/{typeComponent}{accessComponent}.png";

            return(uriString);
        }
Пример #15
0
        /// <summary>
        /// Attempts to build an image URI from the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>The built URI, otherwise null.</returns>
        private string BuildImageURIString(BaseCodeItem codeItem)
        {
            string typeComponent   = GetTypeComponentString(codeItem);
            string accessComponent = GetAccessString(codeItem as BaseCodeItemElement);

            if (typeComponent == null)
            {
                return(null);
            }

            string uriString = string.Format("/SteveCadwallader.CodeMaid;component/UI/ToolWindows/Spade/Images/{0}/{1}{2}.png", ImagePath, typeComponent, accessComponent);

            return(uriString);
        }
Пример #16
0
        /// <summary>
        /// Attempts to move the cursor to the specified code item.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="codeItem">The code item.</param>
        /// <param name="centerOnWhole">True if the whole element should be used for centering.</param>
        internal static void MoveToCodeItem(Document document, BaseCodeItem codeItem, bool centerOnWhole)
        {
            var textDocument = document.GetTextDocument();

            if (textDocument == null)
            {
                return;
            }

            try
            {
                object    viewRangeEnd  = null;
                TextPoint navigatePoint = null;

                codeItem.RefreshCachedPositionAndName();
                textDocument.Selection.MoveToPoint(codeItem.StartPoint, false);

                if (centerOnWhole)
                {
                    viewRangeEnd = codeItem.EndPoint;
                }

                var codeItemElement = codeItem as BaseCodeItemElement;
                if (codeItemElement != null)
                {
                    navigatePoint = codeItemElement.CodeElement.GetStartPoint(vsCMPart.vsCMPartNavigate);
                }

                textDocument.Selection.AnchorPoint.TryToShow(vsPaneShowHow.vsPaneShowCentered, viewRangeEnd);

                if (navigatePoint != null)
                {
                    textDocument.Selection.MoveToPoint(navigatePoint, false);
                }
                else
                {
                    textDocument.Selection.FindText(codeItem.Name, (int)vsFindOptions.vsFindOptionsMatchInHiddenText);
                    textDocument.Selection.MoveToPoint(textDocument.Selection.AnchorPoint, false);
                }
            }
            catch (Exception)
            {
                // Move operation may fail if element is no longer available.
            }
            finally
            {
                // Always set focus within the code editor window.
                document.Activate();
            }
        }
Пример #17
0
        /// <summary>
        /// Determines the drop position for the specified drag event and the drop target.
        /// </summary>
        /// <param name="e">
        /// The <see cref="System.Windows.DragEventArgs" /> instance containing the event data.
        /// </param>
        /// <param name="targetItem">The target item.</param>
        /// <param name="targetElement">The target element.</param>
        /// <returns>The drop position.</returns>
        private static DropPosition GetDropPosition(DragEventArgs e, BaseCodeItem targetItem, TreeViewItem targetElement)
        {
            var  header       = targetElement.Template.FindName("PART_HeaderBorder", targetElement) as FrameworkElement;
            var  targetHeight = header?.ActualHeight ?? targetElement.ActualHeight;
            var  dropPoint    = e.GetPosition(targetElement);
            bool canDropOn    = targetItem is ICodeItemParent;

            if (canDropOn)
            {
                bool isTopThird    = dropPoint.Y <= targetHeight / 3;
                bool isBottomThird = dropPoint.Y > targetHeight * 2 / 3;

                return(isTopThird ? DropPosition.Above : (isBottomThird ? DropPosition.Below : DropPosition.On));
            }

            bool isTopHalf = dropPoint.Y <= targetHeight / 2;

            return(isTopHalf ? DropPosition.Above : DropPosition.Below);
        }
Пример #18
0
        /// <summary>
        /// Determines if the specified code item instance should be followed by a blank line.
        /// Defaults to false for unknown kinds or null objects.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>True if code item should be followed by a blank line, otherwise false.</returns>
        internal bool ShouldInstanceBeFollowedByBlankLine(BaseCodeItem codeItem)
        {
            if (codeItem == null)
            {
                return(false);
            }

            bool shouldKindBeFollowedByBlankLine = ShouldKindBeFollowedByBlankLine(codeItem.Kind);

            if (shouldKindBeFollowedByBlankLine)
            {
                if (codeItem.Kind == KindCodeItem.Field && codeItem.StartPoint.Line == codeItem.EndPoint.Line)
                {
                    return(false);
                }
            }

            return(shouldKindBeFollowedByBlankLine);
        }
Пример #19
0
        /// <summary>
        /// Attempts to get the type component string based on the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>The type component of the partial image name, otherwise null.</returns>
        private static string GetTypeComponentString(BaseCodeItem codeItem)
        {
            switch (codeItem.Kind)
            {
            case KindCodeItem.Class: return("Class");

            case KindCodeItem.Constructor: return("MethodConstructor");

            case KindCodeItem.Delegate: return("Delegate");

            case KindCodeItem.Destructor: return("MethodDestructor");

            case KindCodeItem.Enum: return("Enum");

            case KindCodeItem.Event: return("Event");

            case KindCodeItem.Field:
                var codeItemField = (CodeItemField)codeItem;
                if (codeItemField.IsEnumItem)
                {
                    return("EnumItem");
                }
                if (codeItemField.IsConstant)
                {
                    return("Constant");
                }
                return("Field");

            case KindCodeItem.Interface: return("Interface");

            case KindCodeItem.Method: return("Method");

            case KindCodeItem.Indexer:
            case KindCodeItem.Property: return("Property");

            case KindCodeItem.Region: return("Region");

            case KindCodeItem.Struct: return("Structure");

            default: return(null);
            }
        }
Пример #20
0
        /// <summary>
        /// Shows a context menu for the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <param name="point">The point where the context menu should be shown.</param>
        private void ShowContextMenu(BaseCodeItem codeItem, Point point)
        {
            var viewModel = ViewModel;

            if (codeItem == null || viewModel == null)
            {
                return;
            }

            var menuCommandService = viewModel.Package.MenuCommandService;

            if (menuCommandService != null)
            {
                var contextMenuCommandID = new CommandID(GuidList.GuidCodeMaidContextSpadeBaseGroup, PkgCmdIDList.MenuIDCodeMaidContextSpade);

                viewModel.SelectedItem = codeItem;
                menuCommandService.ShowContextMenu(contextMenuCommandID, (int)point.X, (int)point.Y);
                viewModel.SelectedItem = null;
            }
        }
Пример #21
0
 /// <summary>
 /// Moves the specified item below the specified base.
 /// </summary>
 /// <param name="itemToMove">The item to move.</param>
 /// <param name="baseItem">The base item.</param>
 internal void MoveItemBelowBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
 {
     _undoTransactionHelper.Run(() => RepositionItemBelowBase(itemToMove, baseItem));
 }
Пример #22
0
 /// <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));
 }
Пример #23
0
 /// <summary>
 /// Moves the specified item below the specified base.
 /// </summary>
 /// <param name="itemToMove">The item to move.</param>
 /// <param name="baseItem">The base item.</param>
 internal void MoveItemBelowBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
 {
     new UndoTransactionHelper(_package, "CodeMaid Move Item Below").Run(
         () => RepositionItemBelowBase(itemToMove, baseItem));
 }
 /// <summary>
 /// Moves the specified item above the specified base within an undo transaction.
 /// </summary>
 /// <param name="itemToMove">The item to move.</param>
 /// <param name="baseItem">The base item.</param>
 internal void MoveItemAboveBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
 {
     new UndoTransactionHelper(_package, Resources.CodeMaidMoveItemAbove).Run(
         () => RepositionItemAboveBase(itemToMove, baseItem));
 }
Пример #25
0
 /// <summary>
 /// Determines if the two specified items should be separated by a newline.
 /// </summary>
 /// <param name="firstItem">The first item.</param>
 /// <param name="secondItem">The second item.</param>
 /// <returns>True if the items should be separated by a newline, otherwise false.</returns>
 private bool ShouldBeSeparatedByNewLine(BaseCodeItem firstItem, BaseCodeItem secondItem)
 {
     return(_insertBlankLinePaddingLogic.ShouldBeFollowedByBlankLine(firstItem) ||
            _insertBlankLinePaddingLogic.ShouldBePrecededByBlankLine(secondItem));
 }
Пример #26
0
 /// <summary>
 /// Determines if the specified item is a candidate for deletion.
 /// </summary>
 /// <param name="codeItem">The code item.</param>
 /// <returns>True if the code item can be deleted, otherwise false.</returns>
 private static bool IsDeletable(BaseCodeItem codeItem)
 {
     return(!(codeItem is CodeItemRegion) || !((CodeItemRegion)codeItem).IsPseudoGroup);
 }
Пример #27
0
 /// <summary>
 /// Determines if the specified code item belongs in the specified region.
 /// </summary>
 /// <param name="codeItem">The code item.</param>
 /// <param name="region">The region.</param>
 /// <returns>True if the specified code item belongs in the specified region, otherwise false.</returns>
 private bool CodeItemBelongsInRegion(BaseCodeItem codeItem, CodeItemRegion region)
 {
     return(codeItem != null && _regionComparerByName.Equals(region, ComposeRegionForCodeItem(codeItem)));
 }
Пример #28
0
 /// <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));
 }