Ejemplo n.º 1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Goes to the previous function header.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void GotoFunctionHeaderUp()
        {
            TextSelection sel             = (TextSelection)m_applicationObject.ActiveDocument.Selection;
            TextPoint     curPoint        = sel.ActivePoint;
            CodeElement   codeElement     = GetMethodOrProperty(sel);
            bool          fGotoPrevMethod = true;

            if (codeElement != null)
            {
                TextPoint startPoint = codeElement.StartPoint;
                if (curPoint.AbsoluteCharOffset != startPoint.AbsoluteCharOffset)
                {
                    fGotoPrevMethod = false;
                }
                curPoint = startPoint;
            }
            if (fGotoPrevMethod)
            {
                CodeElement newElement = codeElement;
                while ((newElement == codeElement || newElement == null) && sel.CurrentLine > 1)
                {
                    sel.LineUp(false, 1);
                    newElement = GetMethodOrProperty(sel);
                }
                if (newElement != null)
                {
                    curPoint = newElement.StartPoint;
                }
            }
            sel.MoveToPoint(curPoint, false);
        }
        /// <summary>
        /// Creates a new comment line based on the position of the caret and Doxygen configuration.
        /// </summary>
        /// <param name="currentLine">Current line for reference.</param>
        private void NewCommentLine(string currentLine)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            string startSpaces = currentLine.Replace(currentLine.TrimStart(), "");
            string endSpaces   = currentLine.Replace(currentLine.TrimEnd(), "");

            TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection;

            // Try to also guess proper indentation level based on the current line.
            int oldLine     = ts.ActivePoint.Line;
            int oldOffset   = ts.ActivePoint.LineCharOffset;
            int extraIndent = 0;

            while (!currentLine.StartsWith("/*!"))
            {
                if (m_regexTagSection.IsMatch(currentLine))
                {
                    extraIndent = m_configService.Config.TagIndentation;
                    break;
                }

                ts.LineUp();
                currentLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);
                currentLine = currentLine.TrimStart();
            }

            // Remove extra spaces from the previous line and add tag start line.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.DeleteLeft(endSpaces.Length);

            // TODO: This adds trailing space. Get rid of it similarly to SmartIndent().
            ts.Insert(m_generator.GenerateTagStartLine(startSpaces) + new string(' ', extraIndent));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Extracts comment from the current text selection location.
        /// </summary>
        /// <param name="ts">Text selection.</param>
        /// <param name="comment">Extracted comment</param>
        /// <returns>The start line of the comment. -1, if no comment was found.</returns>
        private int ExtractComment(TextSelection ts, out string comment)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            comment = "";
            string curLine   = "";
            int    startLine = -1;
            int    endLine   = -1;

            do
            {
                ts.LineUp();
                curLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);
                curLine = curLine.TrimStart();

                // Check if we found the beginning of the comment.
                if (curLine.StartsWith("/*!"))
                {
                    startLine = ts.ActivePoint.Line;
                    break;
                }
                // Check for the end of the comment.
                else if (curLine.StartsWith("*/"))
                {
                    endLine = ts.ActivePoint.Line;
                }
            } while (curLine.Length == 0 || curLine.StartsWith("*"));

            if (startLine >= 0 && endLine >= ts.ActivePoint.Line)
            {
                comment = ts.ActivePoint.CreateEditPoint().GetLines(startLine, endLine + 1);
            }

            return(startLine);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Adds the header comment.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <param name="headerComment">The header comment.</param>
        public static void AddHeaderComment(
            this ProjectItem instance,
            string headerComment)
        {
            TextSelection selection = (TextSelection)instance.Document.Selection;

            selection.StartOfDocument();
            selection.NewLine();
            selection.LineUp();
            selection.Text = headerComment;
        }
        /// <summary>
        /// Adds the header comment.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <param name="headerComment">The header comment.</param>
        public static void AddHeaderComment(
            this ProjectItem instance,
            string headerComment)
        {
            TraceService.WriteLine("ProjectItemExtensions::AddHeaderComment");

            TextSelection selection = (TextSelection)instance.Document.Selection;

            selection.StartOfDocument();
            selection.NewLine();
            selection.LineUp();
            selection.Text = headerComment;
        }
Ejemplo n.º 6
0
        public bool ToggleAllRegions(EnvDTE.Document doc, bool closeAll)
        {
            bool          open = false;
            TextSelection ts   = (TextSelection)doc.Selection;

            string startpattern;
            string endpattern;

            if (!this.GetPatterns(doc, out startpattern, out endpattern))
            {
                return(false);
            }
            ts.EndOfDocument(false);
            EditPoint ep = ts.ActivePoint.CreateEditPoint();
            string    line;

            while (!ep.AtStartOfDocument)
            {
                ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
                ts.LineUp(true, 1);
                line = ts.Text.ToLower().Trim();
                if (line.StartsWith(endpattern))
                {
                    open = true;
                }
                else if (line.StartsWith(startpattern))
                {
                    if (closeAll)
                    {
                        if (open)
                        {
                            doc.DTE.ExecuteCommand("Edit.ToggleOutliningExpansion", "");
                        }
                    }
                    else
                    {
                        if (!open)
                        {
                            doc.DTE.ExecuteCommand("Edit.ToggleOutliningExpansion", "");
                        }
                    }
                    open = false;
                }
                ep = ts.ActivePoint.CreateEditPoint();
            }
            toogleRegionDocument = doc;
            ts.Cancel();
            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Scrolls to the beginning of code. Code is searched from below if we are currently on a comment or
        /// empty line. Otherwise the beginning of code is searched from above.
        /// </summary>
        /// <param name="ts"></param>
        /// <returns></returns>
        private bool ScrollToCodeStart(TextSelection ts)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            string curLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);

            curLine = curLine.TrimStart();
            bool codeFound = false;

            // If we are currently on a comment or empty line, find the first code line from below.
            if (IsEmptyOrComment(curLine))
            {
                while (!ts.ActivePoint.AtEndOfDocument)
                {
                    if (!IsEmptyOrComment(curLine))
                    {
                        codeFound = true;
                        break;
                    }

                    ts.LineDown();
                    curLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);
                    curLine = curLine.TrimStart();
                }
            }
            else
            {
                // Otherwise search from above for the line which begins the code statement.
                while (ts.ActivePoint.Line > 1)
                {
                    // Peek previous line and check if it is new code statement, comment or empty.
                    string prevLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line - 1, ts.ActivePoint.Line);
                    prevLine = prevLine.Trim();

                    if (IsEmptyOrComment(prevLine) || prevLine.EndsWith(";") || prevLine.EndsWith("}"))
                    {
                        codeFound = true;
                        break;
                    }

                    ts.LineUp();
                }
            }

            return(codeFound);
        }
Ejemplo n.º 8
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Moves the down after comment.
        /// </summary>
        /// <param name="sel">The sel.</param>
        /// ------------------------------------------------------------------------------------
        private void MoveDownAfterComment(TextSelection sel)
        {
            // Go to the beginning of the line and move down until we find a line that doesn't
            // start with ///.
            while (true)
            {
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.EndOfLine(true);
                if (!sel.Text.StartsWith("///"))
                {
                    break;
                }

                // GhostDoc messes up dashed lines from inherited comments from base class,
                // so delete those
                if (sel.Text.StartsWith("/// -----"))
                {
                    sel.WordRight(true, 1);
                    sel.Delete(1);
                    sel.LineUp(false, 1);
                }
                sel.MoveToLineAndOffset(sel.ActivePoint.Line + 1, 1, false);
            }
        }
Ejemplo n.º 9
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Moves the down after comment.
        /// </summary>
        /// <param name="sel">The sel.</param>
        /// ------------------------------------------------------------------------------------
        private void MoveDownAfterComment(TextSelection sel)
        {
            // Go to the beginning of the line and move down until we find a line that doesn't
            // start with ///.
            while (true)
            {
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.EndOfLine(true);
                if (!sel.Text.StartsWith("///"))
                    break;

                // GhostDoc messes up dashed lines from inherited comments from base class,
                // so delete those
                if (sel.Text.StartsWith("/// -----"))
                {
                    sel.WordRight(true, 1);
                    sel.Delete(1);
                    sel.LineUp(false, 1);
                }
                sel.MoveToLineAndOffset(sel.ActivePoint.Line + 1, 1, false);
            }
        }
Ejemplo n.º 10
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Inserts the method header.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void InsertMethodHeader()
        {
            TextSelection sel = (TextSelection)m_applicationObject.ActiveDocument.Selection;

            CodeElement codeElement = GetMethodOrProperty(sel);

            if (codeElement == null)
            {
                codeElement = sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementClass);
                if (codeElement == null)
                {
                    codeElement = sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementInterface);
                }
                if (codeElement == null || codeElement.StartPoint.Line != sel.ActivePoint.Line)
                {
                    // not a function or property, so just insert /// <summary/>
                    sel.LineUp(false, 1);
                    if (!IsXmlCommentLine)
                    {
                        sel.EndOfLine(false);
                        sel.NewLine(1);
                        sel.Text = "///";
                        sel.LineDown(true, 1);
                        sel.Delete(1);
                        sel.LineUp(false, 1);
                        sel.EndOfLine(false);
                        sel.WordRight(true, 2);
                        sel.Delete(1);
                    }
                    else
                    {
                        sel.LineDown(false, 1);
                    }
                    return;
                }
            }

            sel.MoveToPoint(codeElement.StartPoint, false);

            // Figure out indentation and build dashed line
            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, true);
            string indent = sel.Text;

            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
            string dashedLine = indent + "/// " +
                                new string('-', kLineLen - sel.ActivePoint.VirtualDisplayColumn - 4);

            bool fGhostDoc = true;

            try
            {
                // Use GhostDoc if available
                string addinName = string.Empty;
                foreach (AddIn addin in m_applicationObject.AddIns)
                {
                    if (addin.Name == "GhostDoc")
                    {
                        addinName = (addin.ProgID == "SubMain.GhostDoc.Connect") ?
                                    "Tools.SubMain.GhostDoc.DocumentThis" : "Weigelt.GhostDoc.AddIn.DocumentThis";
                        break;
                    }
                }
                if (addinName != string.Empty)
                {
                    m_applicationObject.ExecuteCommand(addinName, string.Empty);
                }
                else
                {
                    fGhostDoc = false;
                }
            }
            catch
            {
                fGhostDoc = false;
            }

            if (fGhostDoc)
            {
                int nLine       = sel.ActivePoint.Line;
                int nLineOffset = sel.ActivePoint.LineCharOffset;

                // Check to see if we're in the middle of the comment or at the beginning of
                // the method.
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                if (GetMethodOrProperty(sel) == null)
                {
                    // we're in the middle of the comment - move to the end of the comment
                    MoveDownAfterComment(sel);

                    // we're inserting one line (//---) above
                    nLine++;
                }
                else
                {
                    // We are at the beginning of the method.
                    // Check to see if the line above the current line is an attribute. If it is we want to
                    // start there, otherwise we start at the current line.
                    sel.LineUp(false, 1);
                    sel.CharRight(false, 1);
                    if (sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementAttribute) == null)
                    {
                        sel.MoveToLineAndOffset(nLine, 1, false);
                    }

                    // we're inserting two lines above
                    nLine += 2;
                }
                // In case the line is wrapped, we want to go to the real beginning of the line
                sel.MoveToLineAndOffset(sel.ActivePoint.Line, 1, false);
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);

                // Insert a new line and then insert our dashed line.
                sel.Insert(dashedLine + Environment.NewLine, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);

                sel.LineUp(false, 1);
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                MoveUpBeforeComment(sel);

                sel.Insert(Environment.NewLine + dashedLine, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);

                // put IP at previous location
                sel.MoveToLineAndOffset(nLine, nLineOffset, false);
            }
            else
            {
                // check if we already have a comment
                sel.LineUp(false, 1);
                if (!IsXmlCommentLine)
                {
                    // Insert comment
                    sel.EndOfLine(false);
                    sel.NewLine(1);
                    sel.Text = "///";
                }

                // Insert line above
                MoveUpBeforeComment(sel);
                sel.EndOfLine(false);
                sel.NewLine(1);
                sel.Text = dashedLine;
                int upperLine = sel.ActivePoint.Line;
                sel.LineDown(false, 1);

                // reformat text
                for (; IsXmlCommentLine;)
                {
                    int curLine = sel.CurrentLine;
                    // go through all words in this line
                    for (; sel.CurrentLine == curLine; sel.WordRight(false, 1))
                    {
                        if (sel.ActivePoint.VirtualDisplayColumn > kLineLen)
                        {
                            // we have to break before this word
                            sel.WordLeft(true, 1);
                            // skip all punctuation characters
                            for (; sel.Text.Length == 1 && char.IsPunctuation(sel.Text[0]);)
                            {
                                sel.CharLeft(false, 1);                                 // removes selection
                                sel.WordLeft(true, 1);
                            }
                            sel.CharLeft(false, 1);                             // removes selection

                            // break the line
                            sel.NewLine(1);

                            // join next line with remainder of current line
                            sel.EndOfLine(false);
                            sel.LineDown(true, 1);
                            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, true);
                            sel.WordRight(true, 1);
                            sel.Delete(1);

                            // insert a space between the two lines
                            sel.Text = " ";
                        }
                    }
                }

                // Insert line below
                sel.GotoLine(upperLine + 1, false);
                MoveDownAfterComment(sel);
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.NewLine(1);
                sel.LineUp(false, 1);
                sel.Text = dashedLine;
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.LineDown(false, 1);
            }
        }
        /// <summary>
        /// Creates and adds documentation comment blocks when the user types a triple slash.
        /// </summary>
        private void HandleTripleSlash()
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Get the original placement of the cursor in the code editor
            TextSelection ts        = (TextSelection)Dte.ActiveDocument.Selection;
            int           oldLine   = ts.ActivePoint.Line;
            int           oldOffset = ts.ActivePoint.LineCharOffset;

            // Check to see if the previous line starts with a triple-slash; if it does, we should probably
            // just return because there's most likely a docstring already in place.
            ts.LineUp();
            ts.StartOfLine();
            string previousLine = TextView.TextSnapshot.GetLineFromPosition(
                TextView.Caret.Position.BufferPosition.Position).GetText();

            if (previousLine.TrimStart().StartsWith("///"))
            {
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.Insert("/");     // Add the slash that the user just typed
                return;
            }

            // Get the contents of the next line (the one following the original line)
            ts.LineDown();
            ts.LineDown();
            ts.StartOfLine();
            int    currentCharIndex = TextView.Caret.Position.BufferPosition.Position;
            string fullText         = TextView.TextSnapshot.GetText();

            // Check if we just triple-slashed a method (a function or an operation)
            Match methodMatch = GetMethodSignatureMatch(currentCharIndex, fullText);

            if (methodMatch != null)
            {
                Logger.Debug($"Found a potential method match: [{methodMatch.Value}]");
                string signatureString = methodMatch.Groups["Signature"].Value;
                string leadingSpaces   = methodMatch.Groups["Spaces"].Value;

                // Build the summary section, which is going to go in no matter what
                StringBuilder commentBuilder = new StringBuilder();
                commentBuilder.AppendLine("/ # Summary");
                commentBuilder.Append(leadingSpaces + "/// ");

                // Ask the Q# parser application to pull out all of the method details so we know what to
                // put into the documentation comments, and add them if parsing succeeded
                Logger.Debug("Sending a parse request to the Q# parser...");
                try
                {
                    MethodSignatureResponse signature = Messenger.RequestMethodSignatureParse(signatureString);
                    if (signature != null)
                    {
                        Logger.Debug($"Parsing succeeded, method name = [{signature.Name}], " +
                                     $"{signature.ParameterNames.Count} parameters, returns something = {signature.HasReturnType}.");
                        BuildMethodCommentBlock(signature, commentBuilder, leadingSpaces);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error($"Error during method signature request: {ex.GetType().Name} - {ex.Message}");
                    Logger.Trace(ex.StackTrace);
                }

                // Move to the original cursor position and add the comment block to the code
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.Insert(commentBuilder.ToString());
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.LineDown();
                ts.EndOfLine();

                return;
            }

            // Check if we just triple-slashed a new type
            Match newtypeMatch = GetNewTypeMatch(currentCharIndex, fullText);

            if (newtypeMatch != null)
            {
                Logger.Debug($"Found a newtype match: [{newtypeMatch.Value}]");
                string leadingSpaces = newtypeMatch.Groups["Spaces"].Value;

                // Build the summary section
                StringBuilder commentBuilder = new StringBuilder();
                commentBuilder.AppendLine("/ # Summary");
                commentBuilder.Append(leadingSpaces + "/// ");

                // Move to the original cursor position and add the comment block to the code
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.Insert(commentBuilder.ToString());
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.LineDown();
                ts.EndOfLine();

                return;
            }

            // If this was a triple slash on something else, just add the slash and return.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.Insert("/");
        }
Ejemplo n.º 12
0
        protected int ShowEventHandler(string document, string codeBehind, string codeBehindFile, string className, string objectTypeName, string eventName, string eventHandlerName)
        {
            var projectItem = GetProjectItem(document, codeBehind, codeBehindFile);

            var binder = GetBinder(projectItem);

            if (binder == null)
            {
                return(NativeMethods.E_FAIL);
            }

            projectItem.Open(EnvDTE.Constants.vsViewKindCode);

            var function = binder.FindEventHandler(className, objectTypeName, eventName, eventHandlerName);

            if (function != null)
            {
                bool      prevLineIsEmpty = true;
                EditPoint point           = function.EndPoint.CreateEditPoint();
                point.LineUp(1);
                string lines = point.GetLines(point.Line, (int)(point.Line + 1));
                for (int i = 0; i < lines.Length; i++)
                {
                    if (!char.IsWhiteSpace(lines[i]))
                    {
                        prevLineIsEmpty = false;
                        break;
                    }
                }

                Document document2 = projectItem.Document;
                if (document2 != null)
                {
                    Window activeWindow = document2.ActiveWindow;
                    if (activeWindow != null)
                    {
                        TextSelection selection = activeWindow.Selection as TextSelection;
                        if (selection != null)
                        {
                            selection.MoveToPoint(function.EndPoint, false);
                            if (prevLineIsEmpty)
                            {
                                selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                                int virtualCharOffset = selection.AnchorPoint.VirtualCharOffset;
                                selection.LineUp(false, 1);
                                if (selection.AnchorPoint.VirtualCharOffset <= virtualCharOffset)
                                {
                                    int          indentSize = 4;
                                    TextDocument document3  = document2 as TextDocument;
                                    if (document3 != null)
                                    {
                                        indentSize = document3.IndentSize;
                                    }
                                    selection.MoveToLineAndOffset(selection.AnchorPoint.Line, (int)(virtualCharOffset + indentSize), false);
                                }
                            }
                            else
                            {
                                selection.LineUp(false, 1);
                                //selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
                                selection.EndOfLine(false);
                            }
                        }
                    }
                }
            }

            return(NativeMethods.S_OK);
        }
Ejemplo n.º 13
0
        private void EnterTextToActiveDocument(string text)
        {
            if (Statics.DTE.ActiveDocument == null)
            {
                MessageBox.Show("No active document is visible to write the generated code in, copying to clipboard instead (press ctrl-v on the document you want to place the code into)", "No Active Document", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                Clipboard.Clear();
                if (!string.IsNullOrEmpty(text))
                {
                    Clipboard.SetText(text);
                }
                return;
            }
            TextSelection sel   = (TextSelection)Statics.DTE.ActiveDocument.Selection;
            TextRanges    dummy = null;

            if (Statics.Language == ProjectLanguage.CSharp)
            {
                bool isRegionExists = false;

                sel.StartOfDocument(true);
                if (sel.FindPattern("#region Temporary Recording", (int)vsFindOptions.vsFindOptionsMatchInHiddenText, ref dummy))
                {
                    isRegionExists = true;
                }

                sel.EndOfDocument(true);

                sel.FindPattern("}", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsMatchInHiddenText), ref dummy);
                sel.FindPattern("}", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsMatchInHiddenText), ref dummy);
                if (isRegionExists)
                {
                    sel.FindPattern("#endregion", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsMatchInHiddenText), ref dummy);
                }
                sel.LineUp(true, 1);
                if (!isRegionExists)
                {
                    sel.Insert("\t\t#region Temporary Recording Code\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                }
                sel.Insert("\t\tprivate void " + GetAvailableMethodName() + "()\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert("\t\t{\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert(text, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert("\r\n\t\t}\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                if (!isRegionExists)
                {
                    sel.Insert("\t\t#endregion\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                    sel.Insert("\t}\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                }
            }
            else if (Statics.Language == ProjectLanguage.VB)
            {
                sel.EndOfDocument(true);

                sel.FindPattern("End Class", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsMatchInHiddenText), ref dummy);
                //sel.LineUp(true, 1);
                sel.Insert("\tPrivate Sub " + GetAvailableMethodName() + "()\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert(text, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert("\tEnd Sub\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                sel.Insert("End Class\r\n", (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
            }


            //sel.SelectAll();
            Statics.DTE.ActiveDocument.Activate();
            System.Threading.Thread.Sleep(200);
            Statics.DTE.ExecuteCommand("Edit.FormatDocument", string.Empty);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            var dte = Package.GetGlobalService(typeof(DTE)) as DTE;

            if (dte == null || dte.ActiveDocument == null)
            {
                return;
            }

            TextSelection ts = dte.ActiveDocument.Selection as TextSelection;

            // Check if we're at the beginning of the document and should generate a file comment.
            if (ts.ActivePoint.Line == 1)
            {
                string fileComment = m_generator.GenerateFileComment(dte, out int selectedLine);
                ts.DeleteLeft(2); // Removing the // part here.
                ts.Insert(fileComment);

                // Move the caret.
                ts.MoveToLineAndOffset(selectedLine + 1, 1);
                ts.EndOfLine();
                return;
            }

            ts.EndOfLine();

            // Scroll down until we find a non-comment line.
            if (!ScrollToCodeStart(ts))
            {
                return;
            }

            // Save the position so that we know where to place the comment.
            ts.StartOfLine();
            var funcPoint = ts.ActivePoint.CreateEditPoint();
            int oldLine   = ts.ActivePoint.Line;
            int oldOffset = ts.ActivePoint.LineCharOffset;

            ts.EndOfLine();

            // Determine indentation level.
            string currentLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);
            string spaces      = currentLine.Replace(currentLine.TrimStart(), "");

            // Search for the associated code element.
            CodeElement   codeElement = null;
            FileCodeModel fcm         = dte.ActiveDocument.ProjectItem.FileCodeModel;

            if (fcm != null)
            {
                while (codeElement == null)
                {
                    codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);

                    if (ts.ActivePoint.AtEndOfDocument)
                    {
                        break;
                    }

                    if (codeElement == null || !(codeElement is CodeFunction))
                    {
                        codeElement = null;
                        ts.LineDown();
                        ts.EndOfLine();
                    }
                }
            }

            // Extract existing comment if found.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            int startLine = ExtractComment(ts, out string existingDoxyComment);

            // Delete old comment from the text.
            if (startLine >= 0)
            {
                ts.ActivePoint.CreateEditPoint().Delete(funcPoint);
                oldLine   = ts.ActivePoint.Line;
                oldOffset = ts.ActivePoint.LineCharOffset;
            }

            // Generate new comment.
            string doxyComment = m_generator.GenerateComment(spaces, codeElement, existingDoxyComment);

            // Write the doxygen comment to the correct position.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.LineUp();

            // If the upper line is empty, we should go to the start of the line. Otherwise go to the end of the line.
            currentLine = ts.ActivePoint.CreateEditPoint().GetLines(ts.ActivePoint.Line, ts.ActivePoint.Line + 1);

            if (currentLine.Trim().Length == 0)
            {
                ts.StartOfLine();
            }
            else
            {
                ts.EndOfLine();
            }

            ts.Insert("\r\n" + spaces + doxyComment);

            // If this is a new comment, move to the main comment position immediately.
            if (startLine < 0)
            {
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.LineDown();
                ts.EndOfLine();
            }
        }