Incorrect text selected after ReplaceSelectedText

SyntaxEditor for Windows Forms Forum

Posted 16 years ago by Paul Fuller
Version: 4.0.0274
Platform: .NET 2.0
Environment: Windows XP (32-bit)
Avatar
I'm implementing block comment / uncomment functions similar to the EditorView.CommentLines and UncommentLines except that it wraps the selected text in /* ... */

This works however I want the selected text after the operation to be the text that was replaced - either the old text plus the enclosing /*, */ (when adding) or the old text that was contained within the comment (when removing).

There appears to be a problem with the DocumentModificationOptions.SelectInsertedText option to EditorView.ReplaceSelectedText method when the replaced text extends over more than one. The selection is extended by a number of characters equal to the number of newlines in the text.

Looks like a bug. Alternatively is there a better means to achieve this ?

Thanks, Paul
        internal void EditBlockCommentAdd()
        {
            EditorView view = m_SyntaxEditor.SelectedView;
            if (view != null)
            {
                //view.InsertSurroundingText("/*", "*/");  //  Didn't leave the text selected
                if (view.SelectedText != String.Empty)
                {
                    string workText = "/*" + view.SelectedText + "*/";
                    view.ReplaceSelectedText(DocumentModificationType.CommentLines, workText
                        ,DocumentModificationOptions.SelectInsertedText);
                }
            }
        }

        internal void EditBlockCommentRemove()
        {
            EditorView view = m_SyntaxEditor.SelectedView;
            if (view != null)
            {
                string workText = view.SelectedText;

                int pos = workText.IndexOf("/*");
                if (pos >= 0)
                {
                    workText = workText.Remove(pos, 2);
                }

                pos = workText.LastIndexOf("*/");
                if (pos > 0)
                {
                    workText = workText.Remove(pos, 2);
                }

                if (workText != view.SelectedText)
                {
                    view.ReplaceSelectedText(DocumentModificationType.UncommentLines, workText
                        ,DocumentModificationOptions.SelectInsertedText);
                }
            }
        }

Comments (3)

Posted 16 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Paul,

Could you by chance wrap this sort of code in a small project that shows it happening and email that over? I think the problem is that the SelectedText returns the \r\n line ends instead of just \n and the ReplaceSelectedText isn't pulling out the \r's right now when calculating the length to reselect (internally we only use \n). Thanks, this would help us test a before and after change.


Actipro Software Support

Posted 16 years ago by Paul Fuller
Avatar
I expect that you are right about \r\n vs \n being the cause.

Easiest working example is to use your demo application. In TestApplication-CSharp.Net20.sln, MainForm.cs, replace the EditCommentSelection action (around line 4192) with:
                case AppAction.EditCommentSelection:
                    // Comment the currently selected text
                    //editor.SelectedView.CommentLines();
                    string workText = "/*" + editor.SelectedView.SelectedText + "*/";
                    editor.SelectedView.ReplaceSelectedText(DocumentModificationType.CommentLines, workText
                        , DocumentModificationOptions.SelectInsertedText);
                    break;
Replace the EditUncommentSelection action (now around line 4347) with:
                case AppAction.EditUncommentSelection:
                    // Uncomment the currently selected text
                    //editor.SelectedView.UncommentLines();
                    workText = editor.SelectedView.SelectedText;

                    int pos = workText.IndexOf("/*");
                    if (pos >= 0)
                    {
                        workText = workText.Remove(pos, 2);
                    }

                    pos = workText.LastIndexOf("*/");
                    if (pos > 0)
                    {
                        workText = workText.Remove(pos, 2);
                    }

                    if (workText != editor.SelectedView.SelectedText)
                    {
                        editor.SelectedView.ReplaceSelectedText(DocumentModificationType.UncommentLines, workText
                            , DocumentModificationOptions.SelectInsertedText);
                    }
 
                    break;
Build and run. Launch the 'SDI Editor Application', select a block of the sample code and use Edit / Advanced / Comment Selection, then Edit / Advanced / Uncomment Selection.

The text selection grows improperly each time.

Fixing ReplaceSelectedText() is one thing but how about building in the functionality? You already have CommentLines() / UncommentLines(). How about adding CommentBlock(prefix, suffix) and UncommentBlock(prefix, suffix). Also give overloads that don't require the prefix / suffix and provide "/*" and "*/" as the defaults (or whatever the language definition says).
Posted 16 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Thanks Paul, this should now be fixed for the next maintenance release. In the meantime, just strip out the \r chars from the text you pass to ReplaceSelectedText.


Actipro Software Support

The latest build of this product (v24.1.1) was released 28 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.