Exemplo n.º 1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Moves the up before comment.
        /// </summary>
        /// <param name="sel">The sel.</param>
        /// ------------------------------------------------------------------------------------
        private void MoveUpBeforeComment(TextSelection sel)
        {
            TextRanges textRanges = null;

            for (; true;)
            {
                if (sel.FindPattern("\\<summary\\>|/// ---", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsRegularExpression),
                                    ref textRanges))
                {
                    // GhostDoc messes up dashed lines from inherited comments from base class,
                    // so delete those
                    if (sel.Text.StartsWith("/// ---"))
                    {
                        sel.EndOfLine(true);
                        sel.WordRight(true, 1);
                        sel.Delete(1);
                    }
                    else if (sel.Text.StartsWith("<summary>"))
                    {
                        while (true)
                        {
                            sel.MoveToLineAndOffset(sel.ActivePoint.Line - 1, 1, false);
                            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                            sel.EndOfLine(true);
                            if (!sel.Text.StartsWith("///"))
                            {
                                if (sel.Text.Length > 0)
                                {
                                    // there is a non-empty comment line. We want to start at the end
                                    // of it
                                    sel.EndOfLine(false);
                                }
                                else
                                {
                                    sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                                }
                                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);
                            }
                        }
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
        }
        /// <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;
                }
            }
        }
Exemplo n.º 3
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();
     }
 }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        /// <summary>
        /// 选择当前行
        /// </summary>
        public void SelectLine()
        {
            try
            {
                // Retrieve document selection
                TextSelection sel = (TextSelection)_dte.ActiveWindow.Document.Selection;

                // Move to line
                sel.MoveToDisplayColumn(sel.CurrentLine, 1, false);

                // Select from start to end
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.EndOfLine(true);
            }
            catch (ArgumentException)
            {
            }
        }
        private string GetLineText(TextSelection objTextSelection)
        {
            try
            {
                VirtualPoint objActive = objTextSelection.ActivePoint;
                objTextSelection.StartOfLine((EnvDTE.vsStartOfLineOptions)(0), true);
                string text = objTextSelection.Text;
                objTextSelection.EndOfLine(true);
                var result = text + objTextSelection.Text;
                objTextSelection.EndOfLine(false);
                return(result);
            }
            catch (Exception ex)
            {
                ShowMessageBox("GetLineText()", ex.Message);
            }

            return(string.Empty);
        }
Exemplo n.º 7
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);
            }
        }
Exemplo 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);
            }
        }
Exemplo n.º 9
0
        private void postCompileCpp(string generatedFile, int mode, string functionOfInterest, string curCodeLine)
        {
            if (!File.Exists(generatedFile))
            {
                package.showMsgBox("Could not find expected output file\n" + generatedFile);
                return;
            }

            // clean the preprocessed output
            // TODO: do this in a better way
            if (mode == 2)
            {
                var input = new StreamReader(generatedFile);
                generatedFile = Path.GetTempFileName() + ".cpp";
                var output = new StreamWriter(generatedFile);

                while (input.Peek() >= 0)
                {
                    string curReadLine = input.ReadLine();
                    if (curReadLine != "")
                    {
                        output.WriteLine(curReadLine);
                    }
                }
                input.Close();
                output.Close();
            }

            // TODO: there are a thousand ways to open a file
            //			dte.Documents.Open(asmFile, EnvDTE.Constants.vsViewKindCode);
            //			dte.ExecuteCommand("File.OpenFile", asmFile);
            Window       tmp           = dte.ItemOperations.OpenFile(generatedFile, Constants.vsViewKindCode);
            TextDocument genFileWindow = (TextDocument)tmp.Document.Object("TextDocument");

            // crashes VS
            //			bool ddd = genFileWindow.ReplacePattern("^$\n", "", (int)vsFindOptions.vsFindOptionsRegularExpression);
            // http://stackoverflow.com/questions/12453160/remove-empty-lines-in-text-using-visual-studio
            // ^:b*$\n -> ^(?([^\r\n])\s)*\r?$\r?\n

            // now try to find the function the user was looking at

            // if it's a template the fullName will be like ns::bar<T>
            // try to find an instantiation instead then
            int bracketPos = functionOfInterest.IndexOf("<", StringComparison.Ordinal);

            if (bracketPos > 0)
            {
                functionOfInterest = functionOfInterest.Substring(0, bracketPos + 1);
            }

            TextSelection textSelObj = genFileWindow.Selection;

            // first try to find the function
            // TODO: for some reason vsFindOptions.vsFindOptionsFromStart option doesn't work
            textSelObj.StartOfDocument();
            bool res = textSelObj.FindText("PROC ; " + functionOfInterest, (int)vsFindOptions.vsFindOptionsMatchCase);

            if (!res && mode == 1)
            {
                dte.StatusBar.Text = "Couldn't find function '" + functionOfInterest + "'";
                dte.StatusBar.Highlight(true);
            }

            // then search for the code line
            // it might not be there if it's optimized away
            if (!string.IsNullOrWhiteSpace(curCodeLine))
            {
                textSelObj.FindText(curCodeLine.Trim(), (int)vsFindOptions.vsFindOptionsMatchCase);
            }

            textSelObj.StartOfLine();
        }
Exemplo 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("/");
        }
Exemplo n.º 12
0
        private static void addContentToProject(SolutionData solutionData, Project project, DTE2 dte2)
        {
            #region CPP Writing
            if (solutionData.projectType == ProjectType.CppEmpty) //CPP Example
            {
                Directory.CreateDirectory(solutionData.directoryPath + "\\Source Files");
                Directory.CreateDirectory(solutionData.directoryPath + "\\Header Files");

                foreach (ClassData classData in solutionData.classes)
                {
                    #region Class
                    if (classData.classType == ClassType.Class)
                    {
                        Document      doc    = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document;
                        TextSelection txtsel = (TextSelection)doc.Selection;
                        txtsel.Text = "";
                        txtsel.Insert("#include \"" + classData.className + ".h\"\n\n" + classData.className + "::" + classData.className + "()\n{\n}\n\n" + classData.className + "::~" + classData.className + "()\n{\n}");
                        doc.Save(solutionData.directoryPath + "\\Source Files\\" + classData.className + ".cpp");
                        project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Source Files\\" + classData.className + ".cpp");

                        Document      doc2    = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document;
                        TextSelection txtsel2 = (TextSelection)doc2.Selection;
                        txtsel2.Text = "";
                        txtsel2.Insert("#pragma once");
                        if (classData.superClassName != "")
                        {
                            txtsel2.Insert("\n#include \"" + classData.superClassName + "\"");
                        }
                        foreach (string interfaceName in classData.interfaceNames)
                        {
                            txtsel2.Insert("\n#include \"" + interfaceName + "\"");
                        }
                        txtsel2.Insert("\n\nclass " + classData.className);
                        if (classData.superClassName != "")
                        {
                            txtsel2.Insert(" : public " + classData.superClassName);

                            foreach (string interfaceName in classData.interfaceNames)
                            {
                                txtsel2.Insert(", " + interfaceName);
                            }
                        }
                        else if (classData.interfaceNames.Count != 0)
                        {
                            txtsel2.Insert(" : " + classData.interfaceNames[0]);

                            for (int i = 1; i < classData.interfaceNames.Count; ++i)
                            {
                                txtsel2.Insert(", " + classData.interfaceNames[i]);
                            }
                        }
                        txtsel2.Insert("\n{\npublic:\n\t" + classData.className + "();\n\t~" + classData.className + "();\n\nprivate:\n\n};");
                        doc2.Save(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h");
                        project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h");
                    }
                    #endregion
                    #region Enum
                    else if (classData.classType == ClassType.Enum)
                    {
                        EnvDTE.Document doc2    = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document;
                        TextSelection   txtsel2 = (TextSelection)doc2.Selection;
                        txtsel2.Text = "";
                        txtsel2.Insert("#pragma once\n\nenum " + classData.className + "\n{\n\n};");
                        doc2.Save(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h");
                        project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h");
                    }
                    #endregion
                }
            }
            #endregion
            #region C# Writing
            else //C# Example
            {
                foreach (ProjectItem pItem in project.ProjectItems)
                {
                    if (pItem.Name == "Form1.cs")
                    {
                        pItem.Remove();
                    }
                }

                foreach (ClassData classData in solutionData.classes)
                {
                    if (classData.classType == ClassType.Enum || classData.classType == ClassType.Class || classData.classType == ClassType.Interface)
                    {
                        project.ProjectItems.AddFromTemplate(@"C:\Program Files (x86)\Microsoft Visual Studio " + dte2.Version + @"\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class\Class.vstemplate", classData.className + ".cs");
                    }
                    else if (classData.classType == ClassType.Form)
                    {
                        project.ProjectItems.AddFromTemplate(@"c:\Program Files (x86)\Microsoft Visual Studio " + dte2.Version + @"\Common7\IDE\ItemTemplates\CSharp\Windows Forms\1033\Form\windowsform.vstemplate", classData.className + ".cs");
                    }

                    ProjectItem projectItem = null;
                    foreach (ProjectItem pItem in project.ProjectItems)
                    {
                        if (pItem.Name == classData.className + ".cs")
                        {
                            projectItem = pItem;
                            break;
                        }
                    }

                    projectItem.Save();
                    TextSelection txtsel = (TextSelection)projectItem.Document.Selection;

                    #region Class
                    if (classData.classType == ClassType.Class)
                    {
                        txtsel.GotoLine(9);
                        txtsel.EndOfLine();
                        if (classData.superClassName != "")
                        {
                            txtsel.Insert(" : " + classData.superClassName);

                            foreach (string interfaceName in classData.interfaceNames)
                            {
                                txtsel.Insert(", " + interfaceName);
                            }
                        }
                        else if (classData.interfaceNames.Count != 0)
                        {
                            txtsel.Insert(" : " + classData.interfaceNames[0]);

                            for (int i = 1; i < classData.interfaceNames.Count; ++i)
                            {
                                txtsel.Insert(", " + classData.interfaceNames[i]);
                            }
                        }
                    }
                    #endregion
                    #region Enum
                    else if (classData.classType == ClassType.Enum)
                    {
                        txtsel.GotoLine(9);
                        txtsel.StartOfLine();
                        txtsel.CharRight(false, 4);
                        txtsel.DestructiveInsert("enum");
                        txtsel.Delete();
                    }
                    #endregion
                    #region Interface
                    else if (classData.classType == ClassType.Interface)
                    {
                        txtsel.GotoLine(9);
                        txtsel.StartOfLine();
                        txtsel.CharRight(false, 4);
                        txtsel.Insert("interface");
                        txtsel.Delete(5);
                    }
                    #endregion
                }
            }
            #endregion
        }
Exemplo n.º 13
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();
            }
        }
Exemplo n.º 14
0
 private void GetTypeAndNameForOperatorCompletion(ref TextSelection ts, out String typeName, out String varName)
 {
     ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
     ts.EndOfLine(true);
     String lineText = SPTrim(ts.Text);
     int lastGtPos = lineText.IndexOf('>');
     if(lastGtPos == -1) {
         // non-template
         int lastSpPos = lineText.IndexOf(' ');
         typeName = SPTrim(lineText.Substring(0, lastSpPos));
         lineText = SPTrim(lineText.Substring(lastSpPos + 1));
     } else {
         // template code
         int prevGtPos;
         do {
             prevGtPos = lastGtPos;
             lastGtPos = lineText.IndexOf('>', lastGtPos + 1);
         } while(lastGtPos >= 0);
         typeName = SPTrim(lineText.Substring(0, prevGtPos + 1));
         lineText = SPTrim(lineText.Substring(prevGtPos + 1));
     }
     int spPos = lineText.IndexOf(' ');
     if(spPos < 0) {
         varName = SPTrim(lineText);
     } else {
         varName = SPTrim(lineText.Substring(0, spPos));
     }
 }
Exemplo n.º 15
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Moves the up before comment.
        /// </summary>
        /// <param name="sel">The sel.</param>
        /// ------------------------------------------------------------------------------------
        private void MoveUpBeforeComment(TextSelection sel)
        {
            TextRanges textRanges = null;
            for (; true; )
            {
                if (sel.FindPattern("\\<summary\\>|/// ---", (int)(vsFindOptions.vsFindOptionsBackwards | vsFindOptions.vsFindOptionsRegularExpression),
                    ref textRanges))
                {
                    // GhostDoc messes up dashed lines from inherited comments from base class,
                    // so delete those
                    if (sel.Text.StartsWith("/// ---"))
                    {
                        sel.EndOfLine(true);
                        sel.WordRight(true, 1);
                        sel.Delete(1);
                    }
                    else if (sel.Text.StartsWith("<summary>"))
                    {
                        while (true)
                        {
                            sel.MoveToLineAndOffset(sel.ActivePoint.Line - 1, 1, false);
                            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                            sel.EndOfLine(true);
                            if (!sel.Text.StartsWith("///"))
                            {
                                if (sel.Text.Length > 0)
                                {
                                    // there is a non-empty comment line. We want to start at the end
                                    // of it
                                    sel.EndOfLine(false);
                                }
                                else
                                    sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                                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);
                            }
                        }
                        return;
                    }
                }
                else
                    return;
            }
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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);
        }
        // Collapses all regions in the current document
        public static void CollapseAllRegions(DTE dte, Language language, MainPackage package, bool showErrors = true)
        {
            if (IsSupportedLanguage(language))
            {
                dte.SuppressUI = true;                 // Disable UI while we do this
                try
                {
                    // Outling must be enabled.  If Outlining is turned off then the rest of this method will get stuck in an infinite loop.
                    // It can be turned off by default from the C# advanced text editor properties, or it can be turned off by running
                    // the Edit.StopOutlining command (e.g., in the Command window or via Edit -> Outlining -> Stop Outlining).
                    // If the Edit.StartAutomaticOutlining command is available, then that means outlining needs to be turned back on.
                    const string   StartOutliningCommand = "Edit.StartAutomaticOutlining";
                    EnvDTE.Command command = dte.Commands.Item(StartOutliningCommand);
                    if (command.IsAvailable)
                    {
                        dte.ExecuteCommand(StartOutliningCommand);
                    }

                    const string ToggleOutliningExpansion = "Edit.ToggleOutliningExpansion";
                    command = dte.Commands.Item(ToggleOutliningExpansion);
                    const int MaxAttempts = 3;
                    int       maxAttempts = command.IsAvailable ? MaxAttempts : 0;

                    string regionBeginRegex = GetRegionBeginRegex(language);

                    // Sometimes VS can't collapse some regions, so we'll try the whole operation a few times if necessary.
                    bool failedToCollapse = true;
                    for (int attempt = 1; attempt <= maxAttempts && failedToCollapse; attempt++)
                    {
                        failedToCollapse = false;
                        ExpandAllRegions(dte, language);                                       // Force the expansion of all regions

                        TextSelection selection = (TextSelection)dte.ActiveDocument.Selection; // Hook up to the ActiveDocument's selection
                        selection.EndOfDocument();                                             // Shoot to the end of the document

                        // Find the first occurence of #region from the end of the document to the start of the document.
                        int       currentFindOffset  = 0;
                        int       previousFindOffset = int.MaxValue;
                        const int FindOptions        = (int)vsFindOptions.vsFindOptionsBackwards +
                                                       (int)vsFindOptions.vsFindOptionsMatchCase +
                                                       (int)vsFindOptions.vsFindOptionsRegularExpression;
                        while (selection.FindText(regionBeginRegex, FindOptions))
                        {
                            currentFindOffset = selection.TopPoint.AbsoluteCharOffset;
                            if (currentFindOffset >= previousFindOffset)
                            {
                                // I don't want to get stuck in an infinite loop.  I'd rather throw if something unexpected happens.
                                throw new InvalidOperationException(string.Format(
                                                                        "FindText did not go backward!  Previous offset: {0}; Current offset: {1}.",
                                                                        previousFindOffset,
                                                                        currentFindOffset));
                            }

                            // We can ignore matches where #region is used inside a string or single line comment.
                            // However, this still won't detect if it's used inside a multiline comment with the opening
                            // delimiter on another line.
                            selection.SelectLine();
                            string lineText = selection.Text ?? string.Empty;

                            // Make sure the region begin token is the first non-whitespace on the line.
                            Match match = Regex.Match(lineText.TrimStart(), regionBeginRegex);
                            if (match.Success && match.Index == 0)
                            {
                                // The SelectLine call above will leave the end anchor on the next line.  If there's no blank line between
                                // a #region line and an XML doc comment after it, then having the end anchor on the line with the
                                // XML doc comment will cause the comment to collapse instead of the #region.  So we'll avoid that
                                // by moving back to the find offset.
                                selection.MoveToAbsoluteOffset(currentFindOffset);

                                // Try to increase the chances that the ToggleOutliningExpansion command will be available.
                                selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText);

                                // Collapse this #region.  Sometimes VS reports that the Edit.ToggleOutliningExpansion command
                                // isn't available even though it should be.  Poke it and give it a little bit of time to sync up.
                                if (!command.IsAvailable)
                                {
                                    const int WaitMilliseconds = 20;
                                    System.Threading.Thread.Sleep(WaitMilliseconds);
                                    int tempOffset = selection.TopPoint.AbsoluteCharOffset;
                                    selection.CharRight();
                                    selection.MoveToAbsoluteOffset(tempOffset);
                                    System.Threading.Thread.Sleep(WaitMilliseconds);
                                }

                                if (command.IsAvailable)
                                {
                                    // If #region is found in a multiline comment, then this will collapse the enclosing block.
                                    dte.ExecuteCommand(ToggleOutliningExpansion);
                                }
                                else
                                {
                                    // We couldn't collapse a #region.
                                    failedToCollapse = true;
                                }
                            }

                            // Move to the start of the last FindText match, so we can continue searching backward from there.
                            selection.MoveToAbsoluteOffset(currentFindOffset);
                            previousFindOffset = currentFindOffset;
                        }

                        selection.StartOfDocument();                         // All done, head back to the start of the doc
                    }

                    if (failedToCollapse && package != null && showErrors)
                    {
                        package.ShowMessageBox(
                            "Some regions couldn't be collapsed because Visual Studio's Edit.ToggleOutliningExpansion command wasn't available.",
                            true);
                    }
                }
                finally
                {
                    dte.SuppressUI = false;                     // Reenable the UI
                }
            }
        }