Search code examples
c#visual-studio-2015visual-studio-extensions

How to get the text before a selection in visual studio extension


What I want to do

I have written an extension that inserts code at the current cursor. Now I want to be the text depending on what is in front of the cursor.

Examples

Case 1:

// Some comment {insert text here}

Here I want to insert text without the "//" (because its already there)

Case 2:

some Code {insert comment here}

Here I want to insert the text with the "//".

What I currently have

    /// <summary>
    /// Generates the text for an inline comment
    /// </summary>
    /// <returns>The text for an inline comment</returns>
    public string Comment()
    {
        //Get Selection
        var objSel = (TextSelection)_dte2.ActiveDocument.Selection;
        //Save offset
        var offset = objSel.TopPoint.LineCharOffset;
        //move selection to start of line
        objSel.StartOfLine();

        //Get active document
        var activeDoc = _dte2.ActiveDocument.Object() as TextDocument;
        //Get text between selection and offset
        var text = activeDoc.CreateEditPoint(objSel.TopPoint).GetText(offset);

        //move selection back to where it was
        objSel.MoveToLineAndOffset(objSel.TopLine,offset);

        //return text
        return text.Contains("//") ? $@" {GetText()} : " : $"// {GetText()} : ";

    }

The problem

This works for most cases. There are only 2 problems:

  1. In my opinion its not good practice to move the selection around.

  2. When selecting text it will lose the selection and the selection will be empty after the code ran.

I think I could to what I want if I could get a point thats at the start of the line in which my selection is. Then I could put this point in

var text = activeDoc.CreateEditPoint(objSel.TopPoint).GetText(offset);

instead of objSel.TopPoint.

My Question

What is the best way to achieve what I want to do?


Solution

  • I found a solution:

        /// <summary>
        /// Generates the text for an inline comment
        /// </summary>
        /// <returns>The text for an inline comment</returns>
        public string Comment()
        {
            //Get Selection
            var objSel = (TextSelection)_dte2.ActiveDocument.Selection;
    
            //Create EditPoint
            var editPoint = objSel.TopPoint.CreateEditPoint();
            editPoint.StartOfLine();
    
            //Get active document
            var activeDoc = _dte2.ActiveDocument.Object() as TextDocument;
    
            //Get text between EditPoint and Selection
            var text = activeDoc.CreateEditPoint(editPoint).GetText(objSel.TopPoint);
    
            //return text
            return text.Contains("//") ? $" {GetText()} : " : $"// {GetText()} : ";
        }
    

    The key is the lines

    var editPoint = objSel.TopPoint.CreateEditPoint();
    editPoint.StartOfLine();
    

    with this I can create a new point which I will then move to the start of the line and get the text between it and the selections TopPoint