예제 #1
0
        private void SortLines()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                Options options = this.package.Options;

                SortDialog dialog = new SortDialog();
                if (dialog.Execute(options))
                {
                    StringComparison comparison;
                    if (options.SortCompareByOrdinal)
                    {
                        comparison = options.SortCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
                    }
                    else
                    {
                        comparison = options.SortCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
                    }

                    // Now sort the lines and put them back as the selection
                    string    text  = handler.SelectedText;
                    TextLines lines = new TextLines(text);
                    lines.Sort(comparison, options.SortAscending, options.SortIgnoreWhitespace, options.SortIgnorePunctuation, options.SortEliminateDuplicates);
                    string sortedText = lines.ToString();
                    handler.SetSelectedTextIfUnchanged(sortedText, "Sort Lines");
                }
            }
        }
        public MemberSorter(DTE dte, bool findMembers)
        {
            this.textHandler = new TextDocumentHandler(dte);
            this.language    = this.textHandler.Language;

            if (this.textHandler.HasNonEmptySelection &&
                this.textHandler.Document != null &&
                (this.language == Language.CSharp || this.language == Language.VB))
            {
                this.selectionStart = this.textHandler.Selection.TopPoint;
                this.selectionEnd   = this.textHandler.Selection.BottomPoint;

                ProjectItem item = this.textHandler.Document.ProjectItem;
                if (item != null)
                {
                    FileCodeModel2 codeModel = item.FileCodeModel as FileCodeModel2;
                    if (codeModel != null && codeModel.ParseStatus == vsCMParseStatus.vsCMParseStatusComplete)
                    {
                        // For CommandProcessor.CanExecute, we don't actually want to find the members (since
                        // CanExecute is called A LOT).  We just want to know if we got far enough to try.
                        this.CanFindMembers = true;
                        if (findMembers)
                        {
                            this.memberLists = FindMembers(codeModel.CodeElements, this.IsMemberSelected);
                        }
                    }
                }
            }
        }
        public static bool CanAddToDoComment(DTE dte)
        {
            TextDocumentHandler handler = new TextDocumentHandler(dte);
            bool result = handler.TextDocument != null;

            return(result);
        }
예제 #4
0
        private static string GetMemberName(TextDocumentHandler handler, Language language)
        {
            string result = null;

            ThreadHelper.ThrowIfNotOnUIThread();
            if (handler.Document != null && handler.Selection != null)
            {
                // If this doesn't work, then try "HOWTO: Get the code element at the cursor from a Visual Studio
                // .NET macro or add-in" (http://www.mztools.com/articles/2006/mz2006009.aspx).
                VirtualPoint activePoint = handler.Selection.ActivePoint;
                foreach (vsCMElement scope in ElementScopes)
                {
                    try
                    {
                        CodeElement element = activePoint.CodeElement[scope];
                        if (element != null && (scope != vsCMElement.vsCMElementNamespace || NamespaceLanguages.Contains(language)))
                        {
                            result = element.Name;
                            break;
                        }
                    }
#pragma warning disable CC0004 // Catch block cannot be empty. Comment explains.
                    catch (COMException)
                    {
                        // There's no element of the specified type around the specified point.
                    }
#pragma warning restore CC0004 // Catch block cannot be empty
                }
            }

            return(result);
        }
        private static string GetMemberName(TextDocumentHandler handler)
        {
            string result = null;

            if (handler.Document != null && handler.Selection != null)
            {
                // If this doesn't work, then try "HOWTO: Get the code element at the cursor from a Visual Studio
                // .NET macro or add-in" (http://www.mztools.com/articles/2006/mz2006009.aspx).
                VirtualPoint activePoint = handler.Selection.ActivePoint;
                foreach (vsCMElement scope in ElementScopes)
                {
                    try
                    {
                        CodeElement element = activePoint.CodeElement[scope];
                        if (element != null)
                        {
                            result = element.Name;
                            break;
                        }
                    }
                    catch (COMException)
                    {
                        // There's no element of the specified type around the specified point.
                    }
                }
            }

            return(result);
        }
예제 #6
0
        private void Trim()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                Options options = this.package.Options;

                bool execute = true;
                if (!options.OnlyShowTrimDialogWhenShiftIsPressed || Utilities.IsShiftPressed)
                {
                    TrimDialog dialog = new TrimDialog();
                    execute = dialog.Execute(options);
                }

                if (execute && (options.TrimStart || options.TrimEnd))
                {
                    string    text  = handler.SelectedText;
                    TextLines lines = new TextLines(text);
                    lines.Trim(options.TrimStart, options.TrimEnd);
                    string trimmedText = lines.ToString();
                    handler.SetSelectedTextIfUnchanged(trimmedText, "Trim");
                }
            }
        }
        private static void UpdateSelectedText(TextDocumentHandler handler, string commandName, Action <TextLines> updateSelection)
        {
            string    text  = handler.SelectedText;
            TextLines lines = new TextLines(text);

            updateSelection(lines);
            handler.SetSelectedTextIfUnchanged(lines.ToString(), commandName);
        }
예제 #8
0
        private static void UpdateSelectedText(TextDocumentHandler handler, string commandName, Action <TextLines> updateSelection)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            string    text  = handler.SelectedText;
            TextLines lines = new(text);

            updateSelection(lines);
            handler.SetSelectedTextIfUnchanged(lines.ToString(), commandName);
        }
예제 #9
0
        private void ExecuteText()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                Utilities.ShellExecute(handler.SelectedText);
            }
        }
        public static void ListAllProjectProperties(DTE dte)
        {
            StringBuilder output = new StringBuilder();

            List <Project> selectedProjects = new List <Project>();

            if (!GetSelectedProjects(dte, selectedProjects))
            {
                OutputString(output, "One or more projects must be selected in Solution Explorer.");
            }
            else
            {
                bool first = true;
                foreach (Project project in selectedProjects)
                {
                    if (!first)
                    {
                        OutputString(output, Environment.NewLine);
                    }

                    if (project != null)
                    {
                        OutputString(output, project.Name);
                        OutputString(output, Environment.NewLine);

                        const string Indent = "\t";

                        // Show project-level properties
                        OutputProperties(output, project.Properties, Indent);

                        // Show configuration-level properties
                        if (project.ConfigurationManager != null)
                        {
                            foreach (Configuration configuration in project.ConfigurationManager.Cast <Configuration>().OrderBy(c => c.ConfigurationName))
                            {
                                OutputString(output, Environment.NewLine);
                                OutputString(output, Indent);
                                OutputString(output, configuration.ConfigurationName);
                                OutputString(output, Environment.NewLine);

                                OutputProperties(output, configuration.Properties, Indent + Indent);
                            }
                        }
                    }

                    first = false;
                }
            }

            // Example from http://msdn.microsoft.com/en-us/library/envdte.dte.aspx
            dte.ItemOperations.NewFile(@"General\Text File", "Project Properties");
            TextDocumentHandler handler = new TextDocumentHandler(dte);

            handler.SetSelectedText(output.ToString(), "List All Project Properties");
        }
예제 #11
0
        private void Statistics()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                string           text   = handler.SelectedText;
                StatisticsDialog dialog = new StatisticsDialog();
                dialog.Execute(text);
            }
        }
예제 #12
0
        private void StreamText()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                string    text         = handler.SelectedText;
                TextLines lines        = new TextLines(text);
                string    streamedText = lines.Stream();
                handler.SetSelectedTextIfUnchanged(streamedText, "Stream Text");
            }
        }
        public static bool CanCommentSelection(DTE dte, bool comment)
        {
            // First make sure text is selected.  The VS commands don't require that,
            // but visually I don't want the command enabled unless text is selected.
            TextDocumentHandler handler = new TextDocumentHandler(dte);
            bool result = handler.HasNonEmptySelection;

            if (result)
            {
                // My custom logic applies to a subset of the languages that the VS commands
                // support, so I'll use their availability to report my commands's statuses.
                result = CanExecuteVsCommand(dte, comment ? "Edit.CommentSelection" : "Edit.UncommentSelection");
            }

            return(result);
        }
        public static void CommentSelection(DTE dte, MainPackage package, bool comment)
        {
            TextDocumentHandler handler = new TextDocumentHandler(dte);

            if (handler.HasNonEmptySelection)
            {
                Language language         = handler.Language;
                bool     useVsIndentation = GetCommentStyle(
                    language,
                    package.Options.UseVsStyleCommentIndentation,
                    false,
                    out string beginDelimiter,
                    out string endDelimiter);

                // The Edit.CommentSelection and Edit.UncommentSelection commands do 95% of what I want.
                // However, I want to add/remove a space after the opening (and before the closing) delimiter,
                // and I prefer that single-line comments be indented to match the code.  So I'll fallback to the
                // VS commands for any languages I don't have custom logic for.
                bool   useSingleLineStyle         = string.IsNullOrEmpty(endDelimiter);
                bool   useSingleLineVsIndentation = comment && useSingleLineStyle && useVsIndentation;
                string commandName = comment ? "Comment Selection" : "Uncomment Selection";
                if (string.IsNullOrEmpty(beginDelimiter) || useSingleLineVsIndentation)
                {
                    // Nest the undo contexts for the VS command and our additional logic.
                    handler.Execute(
                        commandName,
                        () =>
                    {
                        ExecuteVsCommentCommand(dte, comment);
                        if (!string.IsNullOrEmpty(beginDelimiter) && useSingleLineVsIndentation)
                        {
                            UpdateSelectedText(handler, commandName, lines => lines.AddCommentSpace(beginDelimiter));
                        }
                    });
                }
                else if (useSingleLineStyle)
                {
                    UpdateSelectedText(handler, commandName, lines => lines.Comment(comment, beginDelimiter));
                }
                else
                {
                    UpdateSelectedText(handler, commandName, lines => lines.Comment(comment, beginDelimiter, endDelimiter));
                }
            }
        }
예제 #15
0
        private void GenerateGuid()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.CanSetSelectedText)
            {
                Guid    guid    = Guid.NewGuid();
                Options options = this.package.Options;

                string format;
                switch (options.GuidFormat)
                {
                case GuidFormat.Numbers:
                    format = "N";
                    break;

                case GuidFormat.Braces:
                    format = "B";
                    break;

                case GuidFormat.Parentheses:
                    format = "P";
                    break;

                case GuidFormat.Structure:
                    format = "X";
                    break;

                default:                         // GuidFormat.Dashes
                    format = "D";
                    break;
                }

                string guidText = guid.ToString(format);
                if (options.UppercaseGuids)
                {
                    guidText = guidText.ToUpper();
                }

                // Set the selection to the new GUID
                handler.SetSelectedText(guidText, "Generate GUID");
            }
        }
        public static void AddToDoComment(DTE dte)
        {
            TextDocumentHandler handler = new TextDocumentHandler(dte);

            if (handler.TextDocument != null)
            {
                TextPoint bottomPoint   = handler.Selection.BottomPoint;
                bool      isAtEndOfLine = bottomPoint.AtEndOfLine || IsAtVisibleEndOfLine(bottomPoint);
                Language  language      = handler.Language;
                GetCommentStyle(language, false, !isAtEndOfLine, out string beginDelimiter, out string endDelimiter);

                StringBuilder sb = new StringBuilder();
                sb.Append(beginDelimiter);
                if (sb.Length > 0)
                {
                    sb.Append(' ');
                }

                sb.Append("TODO: ");
                int    noteStartIndex = sb.Length;
                string memberName     = GetMemberName(handler);
                sb.Append("Finish ").Append(memberName ?? "implementation").Append(".");
                int noteLength = sb.Length - noteStartIndex;
                sb.Append(" [").Append(Environment.UserName).Append(", ").Append(DateTime.Now.ToShortDateString()).Append(']');
                if (!string.IsNullOrEmpty(endDelimiter))
                {
                    sb.Append(' ').Append(endDelimiter);
                }

                string comment = sb.ToString();
                handler.SetSelectedText(comment, "Add TODO Comment");

                // Select the note portion in case the user wants to edit it immediately.
                handler.Selection.MoveToAbsoluteOffset(handler.Selection.ActivePoint.AbsoluteCharOffset - comment.Length + noteStartIndex, false);
                handler.Selection.MoveToAbsoluteOffset(handler.Selection.ActivePoint.AbsoluteCharOffset + noteLength, true);
            }
        }
예제 #17
0
        public bool CanExecute(Command command)
        {
            try
            {
                bool result = false;

                if (this.dte != null)
                {
                    switch (command)
                    {
                    // These require a text selection.
                    case Command.SortLines:
                    case Command.Trim:
                    case Command.Statistics:
                    case Command.StreamText:
                    case Command.ExecuteText:
                    case Command.CheckSpelling:
                        result = new TextDocumentHandler(this.dte).HasNonEmptySelection;
                        break;

                    // These require a text selection for specific languages.
                    case Command.CommentSelection:
                    case Command.UncommentSelection:
                        result = CommentHandler.CanCommentSelection(this.dte, command == Command.CommentSelection);
                        break;

                    // These require a document using a supported language.
                    case Command.AddRegion:
                    case Command.CollapseAllRegions:
                    case Command.ExpandAllRegions:
                        result = RegionHandler.IsSupportedLanguage(this.ActiveLanguage);
                        break;

                    // These require an open document with a backing file on disk.
                    case Command.ExecuteFile:
                    case Command.ToggleReadOnly:
                        string fileName = this.GetDocumentFileName();
                        result = File.Exists(fileName);
                        break;

                    case Command.GenerateGuid:
                        result = new TextDocumentHandler(this.dte).CanSetSelectedText;
                        break;

                    case Command.ToggleFiles:
                        result = ToggleFilesHandler.IsSupportedLanguage(this.ActiveLanguage);
                        break;

                    case Command.ListAllProjectProperties:
                        result = ProjectHandler.GetSelectedProjects(this.dte, null);
                        break;

                    case Command.ViewBaseConverter:
                    case Command.ViewTasks:
                        result = true;
                        break;

                    case Command.SortMembers:
                        result = new MemberSorter(this.dte, false).CanFindMembers;
                        break;

                    case Command.AddToDoComment:
                        result = CommentHandler.CanAddToDoComment(this.dte);
                        break;
                    }
                }

                return(result);
            }
            catch (Exception ex)
            {
                MainPackage.LogException(ex);
                throw;
            }
        }
예제 #18
0
        private void CheckSpelling()
        {
            TextDocumentHandler handler = new TextDocumentHandler(this.dte);

            if (handler.HasNonEmptySelection)
            {
                try
                {
                    // Launch Word.
                    Word._Application wordApp = new Word.Application();

                    // Add a document.
                    Word._Document wordDoc = wordApp.Documents.Add();

                    // Clear current contents.
                    Word.Range range = wordApp.Selection.Range;
                    range.WholeStory();
                    range.Delete();
                    range = null;

                    // Add the text the user selected.
                    wordApp.Selection.Text = handler.SelectedText;

                    // Show it
                    wordApp.Visible = true;
                    wordApp.Activate();
                    wordDoc.Activate();

                    // Check spelling
                    wordDoc.CheckSpelling();

                    // Get the edited text back
                    wordApp.Selection.WholeStory();
                    string newText = wordApp.Selection.Text;

                    // Word always adds an extra CR, so strip that off.
                    // Also it converts all LFs to CRs, so change
                    // that back.
                    if (!string.IsNullOrEmpty(newText))
                    {
                        if (newText.EndsWith("\r"))
                        {
                            newText = newText.Substring(0, newText.Length - 1);
                        }

                        newText = newText.Replace("\r", "\r\n");
                    }

                    handler.SetSelectedTextIfUnchanged(newText, "Check Spelling");

                    // Tell the doc and Word to go away.
                    object saveChanges = false;
                    wordDoc.Close(ref saveChanges);
                    wordApp.Visible = false;
                    wordApp.Quit();
                }
                catch (COMException ex)
                {
                    // If we get REGDB_E_CLASSNOTREG, then Word probably isn't installed.
                    const uint REGDB_E_CLASSNOTREG = 0x80040154;
                    if (unchecked ((uint)ex.ErrorCode) == REGDB_E_CLASSNOTREG)
                    {
                        this.package.ShowMessageBox(
                            "Microsoft Word is required in order to check spelling, but it isn't available.\r\n\r\nDetails:\r\n" + ex.Message,
                            true);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }