Ejemplo 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;
                }
            }
        }
Ejemplo n.º 2
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();
        }
        /// <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;
                }
            }
        }
        /// <summary>
        /// 選択中の行を行選択状態にします。
        /// </summary>
        private static void SelectLines(TextSelection selection)
        {
            var bottom = selection.BottomLine;

            selection.MoveToDisplayColumn(selection.TopLine, 1, false);
            selection.MoveToDisplayColumn(bottom, 0, true);
            selection.EndOfLine(true);
        }
        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);
        }
Ejemplo 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();
        }
Ejemplo 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();
        }
Ejemplo n.º 8
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)
            {
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 智能分号:
        ///  * 如果在一行的中间任何位置按下分号,则跳到行结尾添加分号,如果行未已经有一个分号则不重复添加
        ///  * 再按一次分号,则删除在行尾添加的分号,回到刚才的位置插入一个分号
        /// </summary>
        /// <param name="keypress"></param>
        /// <param name="selection"></param>
        /// <param name="inStatementCompletion"></param>
        /// <param name="cancelKeypress"></param>
        public bool BeforeKeyPress(string keypress, TextSelection selection, bool inStatementCompletion, ref bool cancelKeypress)
        {
            if (!selection.IsEmpty || keypress != ";")
            {
                _smartSemicolonFallback = false;
                return(false);
            }

            if (_smartSemicolonFallback && selection.CurrentLine == _smartSemicolonLine &&
                selection.ActivePoint.AtEndOfLine && selection.ActivePoint.CreateEditPoint().GetText(-1) == ";")
            {
                // 重复输入分号, 删除原来行尾的分号,并退回到原位置插入分号
                if (_smartSemicolonDeleteLineEnd)
                {
                    selection.DeleteLeft(1);
                }
                selection.MoveTo(_smartSemicolonLine, _smartSemicolonColumn, false);
                _smartSemicolonFallback = false;
                cancelKeypress          = false;
            }
            else
            {
                // 智能分号,记录位置并移动到行尾插入分号
                _smartSemicolonFallback = true;
                _smartSemicolonLine     = selection.ActivePoint.Line;
                _smartSemicolonColumn   = selection.ActivePoint.DisplayColumn;

                selection.EndOfLine();
                var caret = selection.ActivePoint.CreateEditPoint();

                if (caret.GetText(-1) == ";")
                {
                    cancelKeypress = true;
                    _smartSemicolonDeleteLineEnd = false;
                }
                else
                {
                    cancelKeypress = false;
                    _smartSemicolonDeleteLineEnd = true;
                }
            }

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

                // GhostDoc messes up dashed lines from inherited comments from base class,
                // so delete those
                if (sel.Text.StartsWith("/// -----"))
                {
                    sel.WordRight(true, 1);
                    sel.Delete(1);
                    sel.LineUp(false, 1);
                }
                sel.MoveToLineAndOffset(sel.ActivePoint.Line + 1, 1, false);
            }
        }
Ejemplo n.º 11
0
        private void UpdateComment(CodeFunction function, string oldDoc, int docLine, TextSelection ts, int oldLine, int offset, string lineEnding)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Get the old parameters and return valus
            var    _oldParameters = GetDocLinesOfType(lineEnding, oldDoc, DocLineType._params);
            var    oldParameters  = _oldParameters.Keys.Except(new[] { "__default__" }).ToList();
            var    oldReturns     = GetDocLinesOfType(lineEnding, oldDoc, DocLineType._return);
            string oldReturn      = null;

            if (oldReturns.ContainsKey("return"))
            {
                oldReturn = oldReturns["return"];
            }

            // Get all new function parameters and return value
            var updatedParams = GetFunctionParams(function);
            var updatedType   = function.Type.AsString;

            // Create new comment step by step...
            string newDoc = oldDoc;

            // Remove all old parameters
            foreach (var param in oldParameters)
            {
                // Delete the line(s)
                var pattern = Regex.Escape(_oldParameters[param]) + "( .*" + lineEnding + "|" + lineEnding + ")";
                newDoc = Regex.Replace(newDoc, pattern, "");
            }

            // Remove old return statement
            if (oldReturn != null)
            {
                // Delete the line(s)
                var pattern = Regex.Escape(oldReturns["return"]) + "( .*" + lineEnding + "|" + lineEnding + ")";
                newDoc = Regex.Replace(newDoc, pattern, "");
            }

            // Then add all parameters of the new function
            var _oldParams          = oldParameters.ToList();
            var _uncertainNewParams = new List <string>();
            var newParams           = new Dictionary <string, string>();

            foreach (var param in updatedParams)
            {
                // If there was the exact same parameter, add it again
                if (_oldParams.Contains(param))
                {
                    _oldParams.Remove(param);
                    newParams.Add(param, _oldParameters[param]);
                }
                else
                {
                    newParams.Add(param, null);
                    _uncertainNewParams.Add(param);
                }
            }

            // Check for special cases
            if (_uncertainNewParams.Count > 0 && _oldParams.Count == 0)
            {
                _uncertainNewParams.Clear();
            }
            // If there are no special cases, but still open issues, ask the user
            else if (_uncertainNewParams.Count > 0)
            {
                var dialog = new UpdateDoxygenCommentDialog(_oldParams, _uncertainNewParams);

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Add the selected parameters to the new parameter list
                    var selectedParams = dialog.finalParams;
                    foreach (var param in _uncertainNewParams)
                    {
                        var oldParam = selectedParams[param];
                        if (oldParam != null)
                        {
                            newParams[param] = _oldParameters[oldParam].Replace(oldParam, param);
                        }
                    }
                }
            }

            // Add the new params to the documentation
            foreach (var param in newParams)
            {
                newDoc = AddParamToDoc(lineEnding, newDoc, param.Key, param.Value, _oldParameters);
            }

            // Then add the return statement
            if (!updatedType.Equals("void"))
            {
                newDoc = AddReturnToDoc(lineEnding, newDoc, oldReturn, oldReturns);
            }

            var oldDocLines = oldDoc.Split('\n');
            var lineDiff    = newDoc.Split('\n').Length - oldDocLines.Length;

            ts.MoveToLineAndOffset(docLine + 1, 1);
            ts.MoveToLineAndOffset(docLine + oldDocLines.Length - 1, 1, true);
            ts.EndOfLine(true);
            ts.Insert(newDoc.TrimSuffix(lineEnding));
            ts.MoveToLineAndOffset(oldLine + lineDiff, offset);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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;
            }
        }
Ejemplo n.º 14
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Moves the down after comment.
        /// </summary>
        /// <param name="sel">The sel.</param>
        /// ------------------------------------------------------------------------------------
        private void MoveDownAfterComment(TextSelection sel)
        {
            // Go to the beginning of the line and move down until we find a line that doesn't
            // start with ///.
            while (true)
            {
                sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false);
                sel.EndOfLine(true);
                if (!sel.Text.StartsWith("///"))
                    break;

                // GhostDoc messes up dashed lines from inherited comments from base class,
                // so delete those
                if (sel.Text.StartsWith("/// -----"))
                {
                    sel.WordRight(true, 1);
                    sel.Delete(1);
                    sel.LineUp(false, 1);
                }
                sel.MoveToLineAndOffset(sel.ActivePoint.Line + 1, 1, false);
            }
        }
Ejemplo n.º 15
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();
            }
        }
Ejemplo n.º 16
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
        }
        /// <summary>
        /// Creates and adds documentation comment blocks when the user types a triple slash.
        /// </summary>
        private void HandleTripleSlash()
        {
            ThreadHelper.ThrowIfNotOnUIThread();

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

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

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

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

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

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

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

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

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

                return;
            }

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

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

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

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

                return;
            }

            // If this was a triple slash on something else, just add the slash and return.
            ts.MoveToLineAndOffset(oldLine, oldOffset);
            ts.Insert("/");
        }
Ejemplo n.º 18
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);
            }
        }
Ejemplo n.º 19
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));
     }
 }
        /// <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();
        }
Ejemplo n.º 21
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);
        }
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                ThreadHelper.ThrowIfNotOnUIThread();
                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 if it is a commit character, to generate a multiline comment
                bool isCommitChar = nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN ||
                                    nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB;

                bool showCompletion = nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD;

                // Handle only typed characters or in case of an active completion also deletions
                if (typedChar == '\0' && !isCommitChar && !showCompletion)
                {
                    return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
                }

                // check if the last character of one of the supported shortcuts is typed
                if (!m_provider.CompletionBroker.IsCompletionActive(m_textView) &&
                    m_dte != null &&
                    (typedChar == m_header_char || isCommitChar || typedChar == '!'))
                {
                    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();

                    string typed_shortcut = (currentLine + typedChar).Trim();

                    if (typed_shortcut.Trim().Length >= 3)
                    {
                        // Get the current text properties
                        TextSelection ts         = m_dte.ActiveDocument.Selection as TextSelection;
                        int           oldLine    = ts.ActivePoint.Line;
                        int           oldOffset  = ts.ActivePoint.LineCharOffset;
                        string        lineEnding = GetLineEnding();

                        // First use only single line comment
                        // Single line comments are not supported in the first line, because of the header comment
                        if (typedChar == '*' && typed_shortcut == "/**" && oldLine > 1)
                        {
                            ts.Insert(typedChar + "  ");
                            if (!currentLineFull.Contains("*/"))
                            {
                                ts.Insert("*/");
                            }
                            ts.MoveToLineAndOffset(oldLine, oldOffset + 2);
                            return(VSConstants.S_OK);
                        }

                        // If it is a commit character check if there is a comment to expand
                        if (isCommitChar &&
                            ShouldExpand(ts, currentLineFull, oldLine, oldOffset, out var commentFormat, out var codeElement, out var shortcut))
                        {
                            // Replace all possible comment characters to get the raw brief
                            string currentText = Regex.Replace(currentLineFull.Replace(shortcut, ""), @"\/\*+|\*+\/|\/\/+", "").Trim();

                            // Delete current comment
                            int lenToDelete = Regex.Replace(currentLineFull, @".*\/\*|^[^\/]*\/\/", "").Length;
                            ts.MoveToLineAndOffset(oldLine, oldOffset);
                            ts.EndOfLine();
                            ts.DeleteLeft(lenToDelete);

                            // Create new multiline comment
                            currentLine     = currentLineFull.Substring(0, currentLineFull.Length - lenToDelete);
                            currentLineFull = currentLine;
                            oldOffset       = ts.ActivePoint.LineCharOffset;
                            return(InsertMultilineComment(commentFormat, codeElement, ts, currentLine, lineEnding,
                                                          oldLine, oldOffset, currentText));
                        }

                        // The header can be used without single line format
                        else if (oldLine == 1)
                        {
                            var headerShortcut = m_settings.HeaderFormat.Substring(0, 3);

                            if (typed_shortcut == headerShortcut || typed_shortcut == "/**" || typed_shortcut == "/*!" || typed_shortcut == "///")
                            {
                                // Delete current end comment chars
                                ts.EndOfLine();
                                int lenToDelete = ts.ActivePoint.LineCharOffset - oldOffset;
                                ts.DeleteLeft(lenToDelete);

                                return(InsertMultilineComment(CommentFormat.header, null, ts, currentLine, lineEnding,
                                                              oldLine, oldOffset, ""));
                            }
                        }
                        // '/*!' is a always active shortcut without single line
                        // This is for an eseaier beginning and for the same workflow as older versions
                        else if (typed_shortcut == "/*!")
                        {
                            var _commentFormat = GetCommentFormat(ts, oldLine, oldOffset, out var _codeElement);

                            // Delete current end comment chars
                            ts.EndOfLine();
                            int lenToDelete = ts.ActivePoint.LineCharOffset - oldOffset;
                            ts.DeleteLeft(lenToDelete);

                            return(InsertMultilineComment(_commentFormat, _codeElement, ts, currentLine, lineEnding,
                                                          oldLine, oldOffset, ""));
                        }
                    }
                }

                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)
                        {
                            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 (!m_provider.CompletionBroker.IsCompletionActive(m_textView))
                {
                    if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN)
                    {
                        ITextSnapshotLine currentILine = m_textView.TextSnapshot.GetLineFromPosition(
                            m_textView.Caret.Position.BufferPosition.Position);
                        string currentLine = currentILine.GetText();

                        // TODO: check for being inside a comment block
                        // Insert a '*' when creating a new line in a mutline comment
                        if (currentLine.TrimStart().StartsWith("*") && !currentLine.Contains("*/"))
                        {
                            TextSelection ts         = m_dte.ActiveDocument.Selection as TextSelection;
                            string        spaces     = currentLine.Replace(currentLine.TrimStart(), "");
                            string        lineEnding = GetLineEnding();
                            ts.Insert(lineEnding + spaces + "* ");
                            return(VSConstants.S_OK);
                        }

                        // Insert a '///' when creating a new line in a mutline comment
                        if (currentLine.TrimStart().StartsWith("///"))
                        {
                            TextSelection ts         = m_dte.ActiveDocument.Selection as TextSelection;
                            string        spaces     = currentLine.Replace(currentLine.TrimStart(), "");
                            string        lineEnding = GetLineEnding();
                            ts.Insert(lineEnding + 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 == '\\' || typedChar == '@' || showCompletion)
                {
                    string currentLine = m_textView.TextSnapshot.GetLineFromPosition(
                        m_textView.Caret.Position.BufferPosition.Position).GetText();
                    if (currentLine.TrimStart().StartsWith("*") || 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);
            }
        /// <summary>
        /// Tries to detect the top level function declaration and adds comment if it was a function.
        /// </summary>
        /// <param name="textSelection">The <see cref="TextSelection"/>.</param>
        /// <returns>True if successful; otherwise false.</returns>
        private bool TryAddCommentForTopLevelFunctionDeclaration(TextSelection textSelection, string lineBreak, string indent, int lineNum, int offset)
        {
            // Create an edit point
            var editPoint = textSelection.ActivePoint.CreateEditPoint();

            // Get the function declaration
            string functionLine = editPoint.GetLines(editPoint.Line, editPoint.Line + 1);

            // Check if it's empty or there is no left parentheses
            if (String.IsNullOrEmpty(functionLine) || functionLine.IndexOf('(') < 0)
            {
                return(false);
            }

            // If there is no semi-colon, then find the semi-colon
            if (functionLine.TrimEnd().EndsWith(";"))
            {
                editPoint.EndOfLine();
                editPoint.CharLeft();
            }
            else
            {
                editPoint.EndOfLine();
                editPoint = this.FindFirstMatch(editPoint, ";");
            }
            if (editPoint == null)
            {
                return(false);
            }

            // Get the end of the text
            var endPoint = editPoint.CreateEditPoint();

            endPoint.EndOfLine();
            string text = editPoint.GetText(endPoint);

            // Remove the text and append {}
            editPoint.Delete(endPoint);
            editPoint.Insert("{}");

            var codeElement = editPoint.CodeElement[vsCMElement.vsCMElementFunction];

            if (codeElement == null || !(codeElement is CodeFunction))
            {
                // Remove the text and append original text
                editPoint.CharLeft(2);
                editPoint.Delete(2);
                editPoint.Insert(text);
                textSelection.MoveToLineAndOffset(lineNum, offset);
                return(false);
            }

            // Generate comment for function
            StringBuilder sb = new StringBuilder("/ <summary>" + lineBreak + indent + "/// " + lineBreak + indent + "/// </summary>");

            foreach (CodeElement child in codeElement.Children)
            {
                CodeParameter parameter = child as CodeParameter;
                if (parameter != null)
                {
                    sb.AppendFormat("{0}{1}/// <param name=\"{2}\"></param>", lineBreak, indent, parameter.Name);
                }
            }

            // If there is the return type is not void, generate a returns element
            var function = codeElement as CodeFunction;

            if (function.Type.AsString != "void")
            {
                sb.AppendFormat("{0}{1}/// <returns></returns>", lineBreak, indent);
            }

            // Insert comment
            textSelection.MoveToLineAndOffset(lineNum, offset);
            textSelection.Insert(sb.ToString());

            // Remove the text and append original text
            editPoint.CharLeft(2);
            editPoint.Delete(2);
            editPoint.Insert(text);

            // Move the caret to the summary section
            textSelection.MoveToLineAndOffset(lineNum + 1, offset);
            textSelection.EndOfLine();

            // Return success
            return(true);
        }
Ejemplo n.º 24
0
        private void DoFormat(bool selected)
        {
            if (_dte == null || _dte.ActiveDocument == null)
            {
                return;
            }

            string    text       = "";
            string    initIndent = "";
            EditPoint sp;
            EditPoint sd;

            if (selected)
            {
                TextSelection sel = (TextSelection)_dte.ActiveDocument.Selection;
                sp = sel.TopPoint.CreateEditPoint();
                sd = sel.BottomPoint.CreateEditPoint();
                sel.MoveToLineAndOffset(sp.Line, 1);
                sel.MoveToLineAndOffset(sd.Line, 1, true);
                sel.EndOfLine(true);
                sp   = sel.TopPoint.CreateEditPoint();
                sd   = sel.BottomPoint.CreateEditPoint();
                text = sel.Text;

                foreach (var ch in text)
                {
                    if (ch != ' ' && ch != '\t')
                    {
                        break;
                    }
                    initIndent += ch;
                }
            }
            else
            {
                TextDocument doc = (TextDocument)_dte.ActiveDocument.Object("TextDocument");
                sp   = doc.StartPoint.CreateEditPoint();
                sd   = doc.EndPoint.CreateEditPoint();
                text = sp.GetText(sd);
            }

            if (String.IsNullOrEmpty(text))
            {
                return;
            }

            string eol     = GetEol(text);
            int    lang    = GetLanguage();
            int    sizeOut = 0;
            int    sizeMsg = 0;

            if (NativeMethods.DoFormatter(lang, text, null, ref sizeOut, null, ref sizeMsg, 0, eol, initIndent))
            {
                StringBuilder textOut = new StringBuilder(sizeOut);
                StringBuilder textMsg = new StringBuilder(sizeMsg);
                if (NativeMethods.DoFormatter(lang, text, textOut, ref sizeOut, textMsg, ref sizeMsg, 0, eol, initIndent))
                {
                    ShowOutput(textMsg.ToString());
                    sp.ReplaceText(sd, textOut.ToString(), (int)vsEPReplaceTextOptions.vsEPReplaceTextKeepMarkers);
                }
            }
        }
Ejemplo n.º 25
0
        public static void ApplyPrefeence(DTE2 dte, string region, string controller, string field, string property, string preferredValue)
        {
            //string preferredValue = GetMostPreferredValue(region, controller, field, property);
            List <PreviousPropertyValue> listDefault = new List <PreviousPropertyValue>();

            foreach (ProjectItem pi in dte.Solution.Projects.Item(1).ProjectItems)
            {
                if (pi.ProjectItems != null)
                {
                    foreach (ProjectItem p in pi.ProjectItems)
                    {
                        if (p.Name.EndsWith(".Designer.cs"))
                        {
                            p.Open(EnvDTE.Constants.vsViewKindCode);
                            p.Document.Activate();
                            TextSelection     ts           = (TextSelection)dte.ActiveDocument.Selection;
                            TextSelection     ts2          = (TextSelection)dte.ActiveDocument.Selection;
                            string            srchPattern1 = "new System.Windows.Forms.Button();";
                            EnvDTE.TextRanges textRanges   = null;

                            ts.StartOfDocument(false);

                            int count = 0;

                            string   nameLine = "";
                            string   name     = "";
                            string[] np       = new string[50];

                            while (ts.FindPattern(srchPattern1, 0, ref textRanges))
                            {
                                ts.SelectLine();
                                nameLine = ts.Text;
                                count++;
                                string[] sp  = nameLine.Split('.');
                                string   spi = sp[1];
                                string[] sp2 = spi.Split('=');
                                name      = sp2[0];
                                np[count] = name;
                            }

                            int i = 1;
                            while (ts2.FindPattern(".BackColor = System.Drawing.Color", 0, ref textRanges))
                            {
                                PreviousPropertyValue def = new PreviousPropertyValue();

                                ts2.SelectLine();
                                string codeLine = ts2.Text;
                                codeLine = codeLine.Trim();
                                foreach (string s in np)
                                {
                                    string ss = s;
                                    if (ss != null)
                                    {
                                        ss = ss.Trim();
                                        if (codeLine.Contains(ss) == true)
                                        {
                                            ts2.ReplacePattern(codeLine, "this." + s + ".BackColor = System.Drawing.Color." + preferredValue + ";", 0, ref textRanges);
                                            np                 = np.Where(w => w != s).ToArray();
                                            def.FileName       = p.Name;
                                            def.ControllerType = controller;
                                            def.Property       = property;
                                            def.ControllerName = ss;
                                            def.DefaultValue   = codeLine;
                                            listDefault.Add(def);
                                        }
                                        //else
                                        //{
                                        //    ts2.LineDown();
                                        //    ts2.NewLine();
                                        //    ts2.Insert("this." + np[i] + ".BackColor = System.Drawing.Color." + preferredValue + ";");
                                        //}
                                        //def.FileName = p.Name;
                                        //def.ControllerType = controller;
                                        //def.Property = property;
                                        //def.ControllerName = ss;
                                        //def.DefaultValue = codeLine;
                                        //listDefault.Add(def);
                                    }
                                }

                                //i++;
                            }
                            if (np != null)
                            {
                                foreach (string s in np)
                                {
                                    if (s != null)
                                    {
                                        ts2.EndOfLine();

                                        ts2.NewLine();
                                        ts2.Insert("this." + np[i] + ".BackColor = System.Drawing.Color." + preferredValue + ";");
                                        np = np.Where(w => w != s).ToArray();
                                    }
                                }
                            }
                            SaveDefaultValues(listDefault);
                            dte.ActiveDocument.Save(p.Document.FullName);
                            dte.ActiveDocument.Close(vsSaveChanges.vsSaveChangesNo);
                        }
                    }
                }
            }
        }
        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);
        }
Ejemplo n.º 27
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);
            }
        }
Ejemplo n.º 28
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);
        }
Ejemplo n.º 29
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);
        }