views:

386

answers:

3

I want to make Visual Studio move the autocompleted closing tag a word (or more) to the right. For example, given the following HTML:

<p>I need to emphasize some text.</p>

If I type <em> before the word "emphasize", Visual Studio autocompletes like so:

<p>I need to <em></em>emphasize some text.</p>

Then I need to move the closing </em> to get what I want:

<p>I need to <em>emphasize</em> some text.</p>

Is there a way to make Visual Studio do that last step automatically?

+1  A: 

Hi Hugh,

I don't think this is possible. However, you can configure which HTML tags will be closed automatically:

Tools -> Options -> Text Editor -> HTML -> Format -> "Tag Specific Options" button -> Client HTML Tags -> em -> Closing Tag -> No Closing Tag

Please also consider that automatically moving the closing tagis not trivial (what should be the Word boundary?) and it would cover only a very special use case (only one Word should be e.g. highlighted).

0xA3
It would be nice if there was HTML refactoring type function so you could select what you want inside the tags and then choose 'wrap with' the desired tag.
Jim Anderson
I'd actually prefer something like a CTRL+right arrow that would move the closing tag one word to the right. That way you could do it as many times as needed...
Hugh
@Hugh: Yea, that would be cool too. I actually tried that to see if it would work.
Jim Anderson
+2  A: 

Your question got me thinking how cool it would be if this functionality existed. Luckily, it was pretty simple to implement as a macro in VS. Below is the code for the macro. You can easily bind this to CTRL+ALT+Right using the customization tool in VS.

(Note: I just threw this together quickly being that it's Friday evening)

Sub MoveClosingTag()
    Dim ts As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
    Dim start As EditPoint = ts.ActivePoint.CreateEditPoint()
    Dim tag As String

    ts.WordRight(True)
    If ts.Text = "</" Then
        Do Until ts.ActivePoint.AtEndOfLine
            ts.CharRight(True)
            If ts.Text.EndsWith(">") Then Exit Do
        Loop
        tag = ts.Text
        If tag.EndsWith(">") Then
            ts.Delete()
            ts.WordRight(False)
            ts.Insert(tag, EnvDTE.vsInsertFlags.vsInsertFlagsCollapseToStart)
        Else
            ts.MoveToPoint(start)
        End If
    Else
        ts.MoveToPoint(start)
    End If
End Sub
w4g3n3r
That's great, thanks!
Hugh
+1  A: 

Props to @w4g3n3r for doing the hard work. I've modified the macro a bit to play nicer with spaces.

Note: I find that CTRL+. works nicely as a shortcut key for this; your right ring finger's already on the . key in the use case I originally described.

Sub MoveClosingTag()
    Dim ts As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
    Dim start As EditPoint = ts.ActivePoint.CreateEditPoint()
    Dim tag As String

    ts.WordRight(True)
    If ts.Text = "</" Then
        Do Until ts.ActivePoint.AtEndOfLine
            ts.CharRight(True)
            If ts.Text.EndsWith(">") Then Exit Do
        Loop
        tag = ts.Text
        If tag.EndsWith(">") Then
            ts.Delete()
            Dim pos As Integer
            pos = ts.CurrentColumn
            ts.FindPattern(">", vsFindOptions.vsFindOptionsRegularExpression)
            If ts.CurrentColumn = pos Then
                ts.WordRight(False)
                ts.FindPattern(">", vsFindOptions.vsFindOptionsRegularExpression)
            End If
            ts.Insert(tag, EnvDTE.vsInsertFlags.vsInsertFlagsCollapseToStart)
        Else
            ts.MoveToPoint(start)
        End If
    Else
        ts.MoveToPoint(start)
    End If
End Sub
Hugh