Esempio n. 1
0
        private void JoinLine(TextSelection textSelection)
        {
            // If the selection has no length, try to pick up the next line.
            if (textSelection.IsEmpty)
            {
                textSelection.LineDown(true);
                textSelection.EndOfLine(true);
            }

            const string fluentPattern = @"[ \t]*\r?\n[ \t]*\.";
            const string pattern       = @"[ \t]*\r?\n[ \t]*";

            var selection = textSelection.Text;

            // do regex replace for fluent style
            selection = Regex.Replace(selection, fluentPattern, ".");

            // do regex replace for everything else
            selection = Regex.Replace(selection, pattern, " ");

            textSelection.Text = selection;

            // Move the cursor forward, clearing the selection.
            textSelection.CharRight();
        }
Esempio n. 2
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Gotoes the function header down.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        public void GotoFunctionHeaderDown()
        {
            TextSelection sel      = (TextSelection)m_applicationObject.ActiveDocument.Selection;
            TextPoint     curPoint = sel.ActivePoint;

            try
            {
                CodeElement codeElement = GetMethodOrProperty(sel);
                if (codeElement != null)
                {
                    sel.MoveToPoint(codeElement.EndPoint, false);
                }

                codeElement = null;
                int prevLine = 0;
                while (codeElement == null && prevLine != sel.CurrentLine)
                {
                    prevLine = sel.CurrentLine;
                    sel.LineDown(false, 1);
                    codeElement = GetMethodOrProperty(sel);
                }
                if (codeElement != null)
                {
                    sel.MoveToPoint(codeElement.StartPoint, false);
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Got exception in GotoFunctionHeaderDown: " + e.Message);
            }
        }
        /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
        /// <param term='commandName'>The name of the command to execute.</param>
        /// <param term='executeOption'>Describes how the command should be run.</param>
        /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
        /// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
        /// <param term='handled'>Informs the caller if the command was handled or not.</param>
        /// <seealso class='Exec' />
        public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
        {
            handled = false;
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if (commandName == "FormatVariableDefine.Connect.FormatVariableDefine" ||
                    commandName == "FormatVariableDefine.Connect.FormatVariableDefineRightClick")
                {
                    TextSelection select         = ((TextSelection)_applicationObject.ActiveDocument.Selection);
                    int           nTopLine       = select.TopLine;
                    int           nBottomLine    = select.BottomLine;
                    bool          bLastLineEmpty = select.BottomPoint.AtStartOfLine;
                    select.GotoLine(nTopLine, true);
                    select.LineDown(true, nBottomLine - nTopLine);
                    select.EndOfLine(true);

                    if (bLastLineEmpty)
                    {
                        select.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, true);
                    }
                    string selectedCode = select.Text;
                    string outCode      = CodeSmart.AlignText(selectedCode);       //对齐选中文本
                    select.Insert(outCode, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd);
                    handled = true;
                    return;
                }
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Removes special characters after inserting header
 /// </summary>
 /// <param name="textSelection">Text selection</param>
 /// <param name="template">Template</param>
 private void RemoveSpecialCharacters(TextSelection textSelection, string template)
 {
     // Remove special characters from beginning of each line in template
     textSelection.StartOfDocument();
     for (int i = 0; i < template.Split('\n').Length; i++)
     {
         textSelection.StartOfLine();
         textSelection.CharRight(true, SpecialCharacters.Length);
         textSelection.Delete();
         textSelection.LineDown();
     }
 }
Esempio n. 5
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);
        }
Esempio n. 6
0
        /// <summary>
        /// Joins the text within the specified text selection.
        /// </summary>
        /// <param name="textSelection">The text selection.</param>
        private void JoinText(TextSelection textSelection)
        {
            // If the selection has no length, try to pick up the next line.
            if (textSelection.IsEmpty)
            {
                textSelection.LineDown(true);
                textSelection.EndOfLine(true);
            }

            const string pattern     = @"[ \t]*\r?\n[ \t]*";
            const string replacement = @" ";

            // Substitute all new lines (and optional surrounding whitespace) with a single space.
            TextDocumentHelper.SubstituteAllStringMatches(textSelection, pattern, replacement);

            // Move the cursor forward, clearing the selection.
            textSelection.CharRight();
        }
Esempio n. 7
0
        /// <summary>
        /// Joins the text within the specified text selection.
        /// </summary>
        /// <param name="textSelection">The text selection.</param>
        private void JoinText(TextSelection textSelection)
        {
            // If the selection has no length, try to pick up the next line.
            if (textSelection.IsEmpty)
            {
                textSelection.LineDown(true);
                textSelection.EndOfLine(true);
            }

            const string pattern = @"[ \t]*\r?\n[ \t]*";
            const string replacement = @" ";

            // Substitute all new lines (and optional surrounding whitespace) with a single space.
            TextDocumentHelper.SubstituteAllStringMatches(textSelection, pattern, replacement);

            // Move the cursor forward, clearing the selection.
            textSelection.CharRight();
        }
Esempio n. 8
0
        private bool CheckIfInDocumentetFunction(TextSelection ts, int currentLine, int currentOffset, out CodeFunction codeFunction, out int functionLine)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Get comment beginnings
            string commentFormat = m_settings.FunctionFormat;

            string[] formatLines   = commentFormat.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
            string   commentStart  = formatLines.First().Trim().Split(' ').First().Trim();
            string   commentMiddle = formatLines[1].Trim().Split(' ').First().Trim();
            string   commentEnd    = formatLines.Last().Trim().Split(' ').First().Trim();

            // Check if in comment
            bool isComment = false;

            functionLine = currentLine;
            string line = m_textView.TextSnapshot.GetLineFromPosition(m_textView.Caret.Position.BufferPosition.Position).GetText().Trim();

            if (line.StartsWith(commentStart) || line.StartsWith(commentMiddle) || line.StartsWith(commentEnd))
            {
                while (!ts.ActivePoint.AtEndOfDocument)
                {
                    // Get the line of the curser
                    string _line = m_textView.TextSnapshot.GetLineFromLineNumber(ts.ActivePoint.Line - 1).GetText();

                    // Check if the comment ends
                    if (_line.Contains(commentEnd))
                    {
                        functionLine = ts.ActivePoint.Line + 1;
                        isComment    = true;
                        break;
                    }

                    // If the end of the comment was not there, go one line down
                    ts.LineDown();
                }

                // If there is a comment start, but no correct ending, this is not a doxygen documentation
                if (functionLine == currentLine)
                {
                    codeFunction = null;
                    return(false);
                }
            }

            codeFunction = null;
            CodeElement   codeElement = null;
            FileCodeModel fcm         = m_dte.ActiveDocument.ProjectItem.FileCodeModel;

            if (fcm != null)
            {
                // Move to end of the current line
                ts.MoveToLineAndOffset(functionLine, 1);
                ts.EndOfLine();

                // Check if there is a function
                for (int lineNumber = functionLine; lineNumber <= functionLine + 3; lineNumber++)
                {
                    codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);

                    if (codeElement != null && codeElement.Kind == vsCMElement.vsCMElementFunction)
                    {
                        functionLine = lineNumber;
                        break;
                    }

                    // Only search in the next line if the cursor was in the documentation
                    if (!isComment)
                    {
                        break;
                    }

                    string _line = m_textView.TextSnapshot.GetLineFromLineNumber(lineNumber - 1).GetText().Trim();
                    // If there was an empty line, check next one
                    if (_line.Length == 0)
                    {
                        ts.LineDown();
                        ts.EndOfLine();
                    }
                    // Otherwise the comment is not for a function
                    else
                    {
                        return(false);
                    }
                }
            }

            bool isFunction = codeElement != null && codeElement.Kind == vsCMElement.vsCMElementFunction;

            if (isFunction)
            {
                codeFunction = codeElement as CodeFunction;

                return(codeFunction != null);
            }

            // Return if the line containes a function or not
            return(isFunction);
        }
Esempio n. 9
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("/");
        }
        /// <summary>
        /// Generates a Doxygen comment block to the current caret location.
        /// </summary>
        private void GenerateComment()
        {
            var    currentILine = m_textView.TextSnapshot.GetLineFromPosition(m_textView.Caret.Position.BufferPosition.Position);
            int    len          = m_textView.Caret.Position.BufferPosition.Position - currentILine.Start.Position;
            string currentLine  = m_textView.TextSnapshot.GetText(currentILine.Start.Position, len);
            string spaces       = currentLine.Replace(currentLine.TrimStart(), "");

            ThreadHelper.ThrowIfNotOnUIThread();
            TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection;

            // Save current care position.
            int oldLine   = ts.ActivePoint.Line;
            int oldOffset = ts.ActivePoint.LineCharOffset;

            // Check if we're at the beginning of the document and should generate a file comment.
            if (oldLine == 1)
            {
                string fileComment = m_generator.GenerateFileComment(m_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;
            }

            // Search for the associated code element for which to generate the comment.
            CodeElement codeElement = null;

            ts.LineDown();
            ts.EndOfLine();

            FileCodeModel fcm = m_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)
                    {
                        ts.LineDown();
                    }
                }
            }

            // Generate the comment and add it to the document.
            string doxyComment = m_generator.GenerateComment(spaces, codeElement, "");

            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.DeleteLeft(2); // Removing the // part here.
            ts.Insert(doxyComment);

            // Move caret to the position where the main comment will be written.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.LineDown();
            ts.EndOfLine();
        }
Esempio n. 12
0
        private void method_6(object sender, RoutedEventArgs e)
        {
            Func <Document, bool> func = null;

            if (this.mainViewModel_0 != null && this.mainViewModel_0.SelectedSimilarity != null && this.mainViewModel_0.SelectedSimilarity.OtherFile != null && !string.IsNullOrEmpty(this.mainViewModel_0.SelectedSimilarity.OtherFile.Path))
            {
                if (!Window1.bool_0)
                {
                    try
                    {
                        System.Diagnostics.Process.Start("\"" + this.mainViewModel_0.SelectedSimilarity.OtherFile.Path + "\"");
                        return;
                    }
                    catch (Exception)
                    {
                        System.Windows.MessageBox.Show("Couldn't open the file");
                        return;
                    }
                }
                try
                {
                    DTE2 dTE = null;
                    try
                    {
                        System.Diagnostics.Process[] processesByName = System.Diagnostics.Process.GetProcessesByName("devenv");
                        if (processesByName.Length > 0)
                        {
                            Window1.ShowWindow(processesByName[processesByName.Length - 1].MainWindowHandle, 4);
                            Window1.SetForegroundWindow(processesByName[processesByName.Length - 1].MainWindowHandle);
                        }
                        dTE = (DTE2)Marshal.GetActiveObject(Window1.string_0);
                    }
                    catch (Exception)
                    {
                        System.Diagnostics.Process.Start("\"" + this.mainViewModel_0.SelectedSimilarity.OtherFile.Path + "\"");
                    }
                    if (dTE != null)
                    {
                        System.Diagnostics.Process[] processesByName = System.Diagnostics.Process.GetProcessesByName("devenv");
                        if (processesByName.Length > 0)
                        {
                            Window1.ShowWindow(processesByName[processesByName.Length - 1].MainWindowHandle, 4);
                            Window1.SetForegroundWindow(processesByName[processesByName.Length - 1].MainWindowHandle);
                        }
                        dTE = (DTE2)Marshal.GetActiveObject(Window1.string_0);
                    }
                    dTE.ItemOperations.OpenFile(this.mainViewModel_0.SelectedSimilarity.OtherFile.Path, "{7651A703-06E5-11D1-8EBD-00A0C90F26EA}");
                    IEnumerable <Document> enumerable = dTE.Documents.Cast <Document>().ToList <Document>();
                    foreach (Document current in enumerable)
                    {
                        Console.WriteLine(current.FullName);
                    }
                    IEnumerable <Document> arg_1E4_0 = enumerable;
                    if (func == null)
                    {
                        func = new Func <Document, bool>(this.method_22);
                    }
                    Document      document      = arg_1E4_0.Where(func).First <Document>();
                    TextSelection textSelection = (TextSelection)document.Selection;
                    textSelection.GotoLine(this.mainViewModel_0.SelectedSimilarity.OtherRange.Start + 1, false);
                    textSelection.LineDown(true, this.mainViewModel_0.SelectedSimilarity.OtherRange.Length - 1);
                    document.Activate();
                }
                catch
                {
                }
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Generates a Doxygen comment block to the current caret location.
        /// </summary>
        private void GenerateComment()
        {
            var    currentILine = m_textView.TextSnapshot.GetLineFromPosition(m_textView.Caret.Position.BufferPosition.Position);
            int    len          = m_textView.Caret.Position.BufferPosition.Position - currentILine.Start.Position;
            string currentLine  = m_textView.TextSnapshot.GetText(currentILine.Start.Position, len);
            string spaces       = currentLine.Replace(currentLine.TrimStart(), "");
            string next2char    = m_textView.TextSnapshot.GetText(currentILine.Start.Position + len, 2);

            ThreadHelper.ThrowIfNotOnUIThread();
            TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection;

            // Save current care position.
            int oldLine   = ts.ActivePoint.Line;
            int oldOffset = ts.ActivePoint.LineCharOffset;

            // Removing the auto inserted "*/"
            if (next2char == "*/")
            {
                ts.Delete(2);
            }

            // Check if we're at the beginning of the document and should generate a file comment.
            if (oldLine == 1)
            {
                string fileComment = m_generator.GenerateFileComment(m_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;
            }

            // Search for the associated code element for which to generate the comment.
            CodeElement codeElement = null;

            ts.LineDown();
            ts.EndOfLine();

            FileCodeModel fcm = this.GetFileCodeModel(m_dte.ActiveDocument);

            if (fcm != null)
            {
                while (codeElement == null)
                {
                    codeElement = CodeElementFromPoint(fcm, ts.ActivePoint,
                                                       vsCMElement.vsCMElementNamespace,
                                                       vsCMElement.vsCMElementClass,
                                                       vsCMElement.vsCMElementStruct,
                                                       vsCMElement.vsCMElementEnum,
                                                       vsCMElement.vsCMElementFunction,
                                                       vsCMElement.vsCMElementUnion);

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

                    if (codeElement == null)
                    {
                        ts.LineDown();
                    }
                }

                // if active line is in function body, set codeElement to null
                if (codeElement is CodeFunction function && oldLine > codeElement.StartPoint.Line && oldLine < codeElement.EndPoint.Line)
                {
                    codeElement = null;
                }
            }

            // Generate the comment and add it to the document.
            string doxyComment = m_generator.GenerateComment(spaces, codeElement, "");

            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.DeleteLeft(2); // Removing the // part here.
            ts.Insert(doxyComment);


            if (!m_generator.UseSingleLineComment(codeElement))
            {
                // Move caret to the position where the main comment will be written.
                ts.MoveToLineAndOffset(oldLine, oldOffset);
                ts.LineDown();
                ts.EndOfLine();
            }
            else
            {
                ts.MoveToLineAndOffset(oldLine, oldOffset + 2);
            }
        }
Esempio 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();
            }
        }
Esempio n. 15
0
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
                {
                    return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }

                // make a copy of this so we can look at it after forwarding some commands
                uint commandID = nCmdID;
                char typedChar = char.MinValue;

                // make sure the input is a char before getting it
                if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
                {
                    typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                }

                // check for the triple slash
                if (typedChar == '/' && m_dte != null)
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if ((currentLine + "/").Trim() == "///")
                    {
                        // Calculate how many spaces
                        string        spaces    = currentLine.Replace(currentLine.TrimStart(), "");
                        TextSelection ts        = m_dte.ActiveDocument.Selection as TextSelection;
                        int           oldLine   = ts.ActivePoint.Line;
                        int           oldOffset = ts.ActivePoint.LineCharOffset;
                        ts.LineDown();
                        ts.EndOfLine();

                        CodeElement   codeElement = null;
                        FileCodeModel fcm         = m_dte.ActiveDocument.ProjectItem.FileCodeModel;
                        if (fcm != null)
                        {
                            codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);
                        }

                        if (codeElement != null && codeElement is CodeFunction)
                        {
                            CodeFunction  function = codeElement as CodeFunction;
                            StringBuilder sb       = new StringBuilder("/ <summary>\r\n" + spaces + "/// \r\n" + spaces + "/// </summary>");
                            foreach (CodeElement child in codeElement.Children)
                            {
                                CodeParameter parameter = child as CodeParameter;
                                if (parameter != null)
                                {
                                    sb.AppendFormat("\r\n" + spaces + "/// <param name=\"{0}\"></param>", parameter.Name);
                                }
                            }

                            if (function.Type.AsString != "void")
                            {
                                sb.AppendFormat("\r\n" + spaces + "/// <returns></returns>");
                            }

                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.Insert(sb.ToString());
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.Insert("/ <summary>\r\n" + spaces + "/// \r\n" + spaces + "/// </summary>");
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                    }
                }

                if (m_session != null && !m_session.IsDismissed)
                {
                    // check for a commit character
                    if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                        nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB ||
                        typedChar == '>')
                    {
                        // check for a selection
                        // if the selection is fully selected, commit the current session
                        if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            string selectedCompletion = m_session.SelectedCompletionSet.SelectionStatus.Completion.DisplayText;
                            m_session.Commit();
                            TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection;
                            switch (selectedCompletion)
                            {
                            case "<!-->":
                                ts.CharLeft(false, 3);
                                break;

                            case "<![CDATA[>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<c>":
                                ts.CharLeft(false, 4);
                                break;

                            case "<code>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<example>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<exception>":
                                ts.CharLeft(false, 14);
                                break;

                            case "<include>":
                                ts.CharLeft(false, 21);
                                break;

                            case "<list>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<para>":
                                ts.CharLeft(false, 7);
                                break;

                            case "<param>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<paramref>":
                                ts.CharLeft(false, 13);
                                break;

                            case "<permission>":
                                ts.CharLeft(false, 15);
                                break;

                            case "<remarks>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<returns>":
                                ts.CharLeft(false, 10);
                                break;

                            case "<see>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<seealso>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<typeparam>":
                                ts.CharLeft(false, 14);
                                break;

                            case "<typeparamref>":
                                ts.CharLeft(false, 3);
                                break;

                            case "<value>":
                                ts.CharLeft(false, 8);
                                break;

                            default:
                                break;
                            }

                            // also, don't add the character to the buffer
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            // if there is no selection, dismiss the session
                            m_session.Dismiss();
                        }
                    }
                }
                else
                {
                    if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                    {
                        string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                            m_textView.Caret.Position.BufferPosition.Position).GetText();
                        if (currentLine.TrimStart().StartsWith("///"))
                        {
                            TextSelection ts     = m_dte.ActiveDocument.Selection as TextSelection;
                            string        spaces = currentLine.Replace(currentLine.TrimStart(), "");
                            ts.Insert("\r\n" + spaces + "/// ");
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // pass along the command so the char is added to the buffer
                int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                if (typedChar == '<')
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if (currentLine.TrimStart().StartsWith("///"))
                    {
                        if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
                        {
                            if (this.TriggerCompletion())
                            {
                                m_session.SelectedCompletionSet.SelectBestMatch();
                                m_session.SelectedCompletionSet.Recalculate();
                                return(VSConstants.S_OK);
                            }
                        }
                    }
                }
                else if (
                    commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                    commandID == (uint)VSConstants.VSStd2KCmdID.DELETE ||
                    char.IsLetter(typedChar))
                {
                    if (m_session != null && !m_session.IsDismissed) // the completion session is already active, so just filter
                    {
                        m_session.SelectedCompletionSet.SelectBestMatch();
                        m_session.SelectedCompletionSet.Recalculate();
                        return(VSConstants.S_OK);
                    }
                }

                return(retVal);
            }
            catch
            {
            }

            return(VSConstants.E_FAIL);
        }
Esempio n. 16
0
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
                {
                    return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }

                // make a copy of this so we can look at it after forwarding some commands
                uint commandID = nCmdID;
                char typedChar = char.MinValue;

                // make sure the input is a char before getting it
                if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
                {
                    typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                }
                if (m_dte != null)
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();

                    // check for the Javadoc slash and two asterisk pattern while compensating for visual studio's block comment closing generation
                    if (typedChar == '*' && currentLine.Trim() == "/**/")
                    {
                        // Calculate how many spaces
                        string        spaces = currentLine.Replace(currentLine.TrimStart(), "");
                        TextSelection ts     = m_dte.ActiveDocument.Selection as TextSelection;
                        //Remember where the cursor was when command was triggered
                        int oldLine   = ts.ActivePoint.Line;
                        int oldOffset = ts.ActivePoint.LineCharOffset;
                        ts.LineDown();
                        ts.EndOfLine();
                        ts.SelectLine();

                        //Detect and skip over Unreal Engine Function Macros
                        string trimmedFuncLine = ts.Text.Trim();
                        if (trimmedFuncLine != "" && trimmedFuncLine.StartsWith("UFUNCTION("))
                        {
                            ts.EndOfLine();
                        }
                        else
                        {
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                        }

                        CodeElement   codeElement = null;
                        FileCodeModel fcm         = m_dte.ActiveDocument.ProjectItem.FileCodeModel;
                        if (fcm != null)
                        {
                            codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);
                        }

                        if (codeElement != null && codeElement is CodeFunction)
                        {
                            CodeFunction  function         = codeElement as CodeFunction;
                            StringBuilder sb               = new StringBuilder("*");
                            bool          isNoArgsNoReturn = true;
                            foreach (CodeElement child in codeElement.Children)
                            {
                                CodeParameter parameter = child as CodeParameter;
                                if (parameter != null)
                                {
                                    sb.AppendFormat("\r\n" + spaces + " * @param {0} ", parameter.Name);
                                    isNoArgsNoReturn = false;
                                }
                            }

                            if (function.Type.AsString != "void")
                            {
                                isNoArgsNoReturn = false;
                                if (function.Type.AsString == "bool")
                                {
                                    sb.AppendFormat("\r\n" + spaces + " * @return true \r\n" + spaces + " * @return false ");
                                }
                                else
                                {
                                    sb.AppendFormat("\r\n" + spaces + " * @return ");
                                }
                            }

                            //If function has a return type or parameters then we generate them and return, otherwise we skip to generate a single line comment
                            if (!isNoArgsNoReturn)
                            {
                                sb.Insert(1, "\r\n" + spaces + " * ");
                                sb.AppendFormat("\r\n" + spaces + " ");
                                ts.MoveToLineAndOffset(oldLine, oldOffset);
                                ts.Insert(sb.ToString());
                                ts.MoveToLineAndOffset(oldLine, oldOffset);
                                ts.LineDown();
                                ts.EndOfLine();
                                return(VSConstants.S_OK);
                            }
                        }
                        //For variables and void functions with no parameters we can do a single line comment
                        ts.MoveToLineAndOffset(oldLine, oldOffset);
                        ts.Insert("*  ");
                        ts.MoveToLineAndOffset(oldLine, oldOffset + 2);
                        return(VSConstants.S_OK);
                    }
                    else if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                    {
                        //Get text on current line before and after cursor
                        TextSelection ts        = m_dte.ActiveDocument.Selection as TextSelection;
                        int           oldLine   = ts.ActivePoint.Line;
                        int           oldOffset = ts.ActivePoint.LineCharOffset;
                        ts.EndOfLine(true);
                        string afterCursor = ts.Text;
                        ts.MoveToLineAndOffset(oldLine, oldOffset);
                        ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, true);
                        string beforeCursor        = ts.Text;
                        string beforeCursorTrimmed = beforeCursor.TrimStart();
                        ts.MoveToLineAndOffset(oldLine, oldOffset);

                        // Calculate how many spaces
                        string spaces = beforeCursorTrimmed == "" ? beforeCursor : beforeCursor.Replace(beforeCursorTrimmed, "");

                        bool hasAsteriskBeforeCursor               = beforeCursorTrimmed == "" ? false : beforeCursorTrimmed.StartsWith("* ");
                        bool hasBlockTerminatorAfterCursor         = afterCursor == "" ? false : afterCursor.EndsWith("*/");
                        bool hasBlockTerminatorDirectlyAfterCursor = hasBlockTerminatorAfterCursor && afterCursor.Trim() == "*/";

                        //Add a space to maintain correct asterisk alignment if needed
                        if (beforeCursorTrimmed != "" && beforeCursorTrimmed.StartsWith("/*"))
                        {
                            hasAsteriskBeforeCursor = true;
                            spaces += " ";
                        }

                        if (hasAsteriskBeforeCursor)
                        {
                            ts.Insert("\r\n" + spaces);
                            if (!hasBlockTerminatorAfterCursor)
                            {
                                ts.Insert("* ");
                            }
                            else if (hasBlockTerminatorDirectlyAfterCursor)
                            {
                                ts.Delete(afterCursor.Length);
                                ts.Insert("*/");
                                ts.MoveToLineAndOffset(ts.ActivePoint.Line, ts.ActivePoint.LineCharOffset - 2);
                            }
                            return(VSConstants.S_OK);
                        }
                        else if (hasBlockTerminatorAfterCursor)
                        {
                            ts.Insert("* \r\n" + spaces);
                            if (hasBlockTerminatorDirectlyAfterCursor)
                            {
                                ts.Delete(afterCursor.Length);
                                ts.Insert("*/");
                                ts.MoveToLineAndOffset(ts.ActivePoint.Line, ts.ActivePoint.LineCharOffset - 2);
                            }
                            return(VSConstants.S_OK);
                        }
                    }
                }
                // pass along the command so the char is added to the buffer
                return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
            }
            catch
            {
            }

            return(VSConstants.E_FAIL);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider))
                {
                    return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }

                // make a copy of this so we can look at it after forwarding some commands
                uint commandID = nCmdID;
                char typedChar = char.MinValue;

                // make sure the input is a char before getting it
                if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
                {
                    typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                }

                // check for the triple slash
                if (typedChar == '!' && m_dte != null)
                {
                    var currentILine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position);
                    int    len             = m_textView.Caret.Position.BufferPosition.Position - currentILine.Start.Position;
                    string currentLine     = m_textView.TextSnapshot.GetText(currentILine.Start.Position, len);
                    string currentLineFull = currentILine.GetText();

                    if ((currentLine + typedChar).Trim() == "/*!")
                    {
                        // Calculate how many spaces
                        string        spaces    = currentLine.Replace(currentLine.TrimStart(), "");
                        TextSelection ts        = m_dte.ActiveDocument.Selection as TextSelection;
                        int           oldLine   = ts.ActivePoint.Line;
                        int           oldOffset = ts.ActivePoint.LineCharOffset;

                        if (!currentLineFull.Contains("*/"))
                        {
                            ts.Insert("*/");
                        }
                        ts.LineDown();
                        ts.EndOfLine();

                        CodeElement   codeElement = null;
                        FileCodeModel fcm         = m_dte.ActiveDocument.ProjectItem.FileCodeModel;
                        if (fcm != null)
                        {
                            while (codeElement == null)
                            {
                                codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction);

                                if (codeElement == null)
                                {
                                    ts.LineDown();
                                }
                            }
                        }

                        var cls  = codeElement as VCCodeClass;
                        var cls2 = codeElement as CodeClass;
                        var fnc  = codeElement as VCCodeFunction;

                        var kind = codeElement.Kind;

                        if (codeElement != null && codeElement is CodeFunction)
                        {
                            VCCodeFunction function = codeElement as VCCodeFunction;
                            StringBuilder  sb       = new StringBuilder("!\r\n" + spaces + " * \r\n" + spaces + " * ");
                            foreach (CodeElement child in codeElement.Children)
                            {
                                CodeParameter parameter = child as CodeParameter;
                                if (parameter != null)
                                {
                                    sb.AppendFormat("\r\n" + spaces + " * \\param {0}", parameter.Name);
                                }
                            }

                            if (function.Type.AsString != "void")
                            {
                                sb.AppendFormat("\r\n" + spaces + " * \\return ");
                            }

                            sb.AppendFormat("\r\n" + spaces + " ");

                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.Insert(sb.ToString());
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                        else if (codeElement != null && codeElement is VCCodeClass)
                        {
                            VCCodeClass   function = codeElement as VCCodeClass;
                            StringBuilder sb       = new StringBuilder("!\r\n" + spaces + " * \r\n" + spaces + " * ");

                            foreach (CodeElement child in function.TemplateParameters)
                            {
                                CodeParameter parameter = child as CodeParameter;
                                if (parameter != null)
                                {
                                    sb.AppendFormat("\r\n" + spaces + " * \\tparam {0}", parameter.Name);
                                }
                            }

                            sb.AppendFormat("\r\n" + spaces + " ");

                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.Insert(sb.ToString());
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.Insert("!\r\n" + spaces + " * \r\n" + spaces + " * \r\n" + spaces + " ");
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.LineDown();
                            ts.EndOfLine();
                            return(VSConstants.S_OK);
                        }
                    }
                }

                if (m_session != null && !m_session.IsDismissed)
                {
                    // check for a commit character

                    if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                        nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)
                    {
                        // check for a selection
                        // if the selection is fully selected, commit the current session
                        if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            string selectedCompletion = m_session.SelectedCompletionSet.SelectionStatus.Completion.DisplayText;
                            m_session.Commit();

                            // also, don't add the character to the buffer
                            return(VSConstants.S_OK);
                        }
                        else
                        {
                            // if there is no selection, dismiss the session
                            m_session.Dismiss();
                        }
                    }
                }
                else
                {
                    if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                    {
                        string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                            m_textView.Caret.Position.BufferPosition.Position).GetText();
                        if (currentLine.TrimStart().StartsWith("*"))
                        {
                            TextSelection ts     = m_dte.ActiveDocument.Selection as TextSelection;
                            string        spaces = currentLine.Replace(currentLine.TrimStart(), "");
                            ts.Insert("\r\n" + spaces + "* ");
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // pass along the command so the char is added to the buffer
                int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
                if (typedChar == '\\')
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if (currentLine.TrimStart().StartsWith("*"))
                    {
                        if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion
                        {
                            if (this.TriggerCompletion())
                            {
                                m_session.SelectedCompletionSet.SelectBestMatch();
                                m_session.SelectedCompletionSet.Recalculate();
                                return(VSConstants.S_OK);
                            }
                        }
                    }
                }
                else if (
                    commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE ||
                    commandID == (uint)VSConstants.VSStd2KCmdID.DELETE ||
                    char.IsLetter(typedChar))
                {
                    if (m_session != null && !m_session.IsDismissed) // the completion session is already active, so just filter
                    {
                        m_session.SelectedCompletionSet.SelectBestMatch();
                        m_session.SelectedCompletionSet.Recalculate();
                        return(VSConstants.S_OK);
                    }
                }

                return(retVal);
            }
            catch
            {
            }

            return(VSConstants.E_FAIL);
        }