The following macros implement this behaviour. You can remap Ctrl-Right and Ctrl-Left to MoveRightCamelCaseWord and MoveLeftCamelCaseWord.
I've also provided macros that mimic the behaviour of shift-ctrl-arrow, which extend the selection by one word.
Sub MoveRightCamelCaseWord()
MoveCamelCase(1, False)
End Sub
Sub MoveLeftCamelCaseWord()
MoveCamelCase(-1, False)
End Sub
Sub ExtendSelectionRightCamelCaseWord()
MoveCamelCase(1, True)
End Sub
Sub ExtendSelectionLeftCamelCaseWord()
'extending the selection to the left doesn't seem to work.
MoveCamelCase(-1, True)
' so instead I'll move to the left, then select the word to the right.
'MoveCamelCase(-1, False)
'MoveCamelCase(1, True)
End Sub
Function IsCharTypeDifferent(ByVal prevChar As Char, ByVal nextChar As Char)
If (Char.IsLetterOrDigit(prevChar) And Not Char.IsLetterOrDigit(nextChar)) Then
Return True
End If
If (Char.IsWhiteSpace(prevChar) And Not Char.IsWhiteSpace(nextChar)) Then
Return True
End If
If (Char.IsPunctuation(prevChar) And Not Char.IsPunctuation(nextChar)) Then
Return True
End If
Return False
End Function
' move the cursor to the left/right by one word, in this case the definition of a 'word' is changed
' to respect CamelCase. moveDirection is -1 or 1 depending on whether we're moving left or right
Sub MoveCamelCase(ByVal moveDirection As Integer, ByVal extend As Boolean)
Dim sel As TextSelection = DTE.ActiveDocument().Selection()
Dim objAnchor As VirtualPoint = sel.AnchorPoint
Dim finished As Boolean
While (Not finished)
Dim selPoint As VirtualPoint
If (moveDirection > 0) Then
selPoint = sel.BottomPoint()
Else
selPoint = sel.TopPoint()
End If
Dim leftChar, rightChar As Char
Dim editPoint As EditPoint
editPoint = selPoint.CreateEditPoint()
' Move the caret to the right by one
If (moveDirection > 1) Then
editPoint.CharRight(moveDirection)
Else
editPoint.CharLeft(-moveDirection)
End If
sel.MoveToPoint(editPoint, extend)
' Get the two characters surrounding the new caret position.
editPoint.CharLeft(1)
leftChar = editPoint.GetText(1)
editPoint.CharRight(1)
rightChar = editPoint.GetText(1)
' Which character out of these two is the 'prev' and 'next' depends on which direction we're going.
Dim prevChar, nextChar As Char
If (moveDirection > 0) Then
prevChar = leftChar
nextChar = rightChar
Else
prevChar = rightChar
nextChar = leftChar
End If
' Keep repeating the loop until we meet the right conditions for stopping
If (IsCharTypeDifferent(prevChar, nextChar)) Then
finished = True
Else
' Stop when the character to the right is uppercase letter and character to left is lower case.
If (Char.IsLetter(leftChar) And Char.IsLetter(rightChar)) Then
If (Char.IsLower(leftChar) And Char.IsUpper(rightChar)) Then
finished = True
End If
End If
End If
End While
End Sub