6

I'd like to get notified whenever the caret position changed in the active text view. The only thing EnvDTE seems to offer is the LineChanged event, which of-course does not get raised when moving the caret left or right within the same line.

I realize VS2010's Editor Extensibility lets you do this with no sweat, but I need a solution that is backwards compatible with VS2008.

Omer Raviv
  • 11,409
  • 5
  • 43
  • 82
  • Do you have a IVsTextView reference available? – Simon Mourier May 15 '13 at 09:11
  • Yes, and I noticed I can get the caret/selection position from it using `.GetSelection(...)`, but couldn't find an event that notifies me when it's changed. – Omer Raviv May 15 '13 at 09:31
  • I don't think you have that information available in VS2008. The only caret event you can get is OnCaretChangeLine from IVsTextViewEvents. You will have to measure caret position between two events in time. – Simon Mourier May 15 '13 at 09:49
  • @SimonMourier Well, there must be some way, as there are many extensions (Resharper, CodeRush) that work in VS2008 and react to each caret move. – Omer Raviv May 17 '13 at 21:01
  • 1
    Well, yes, there is at least one way like I said. Just create a timer and measure caret position. R# and CodeRush are huge packages that employ many many tricks and hacks. The fact they do something doesn't mean is easy or officially supported. – Simon Mourier May 18 '13 at 06:59

2 Answers2

1

Have you seen this: DTE2 events don't fire

You have to keep a local instance of the Events object, otherwise the event wont fire (I assume because the COM backed Events object went out of scope and was GC'd):

public class MyVSPackage
{ 
   TextEditorEvents _textEditorEvents;

   public MyVSPackage()
   {
        _textEditorEvents = DTE.Events.TextEditorEvents;

        _textEditorEvents.LineChanged += (point, endPoint, hint) => //Do something here
   }
}
Community
  • 1
  • 1
Philip Pittle
  • 11,821
  • 8
  • 59
  • 123
  • Yes, I'm aware of that - but as I wrote in my original post, LineChanged only occurs when the Line changed, and not when the Column changed. Thanks anyways! – Omer Raviv May 23 '13 at 20:18
  • Sorry about that. If you cast dte.Events to an EnvDTE80.Events2, you get access to TextDocumentKeyPressEvents, which has an AfterKeyPress event. Have you tried that? `(dte.Events as Events2).TextDocumentKeyPressEvents.AfterKeyPress += (keypress, selection, completion) => ` – Philip Pittle May 24 '13 at 08:04
  • Unfortunately, that doesn't work either, since AfterKeyPress doesn't fire for all key presses (specifically, the arrow keys do not trigger it to fire, as they are processed earlier in Visual Studio's internal command handling code). – Omer Raviv May 24 '13 at 09:45
0

I found a solution. The solution is to create an IOleCommandTarget and register it on the IVsTextView (See the last two bits of code in this blog post (in Herbrew)). Then, each time a command is fired, I check whether the caret position has changed. See also: this blog post - How to intercept key presses in the Visual Studio text editor

Omer Raviv
  • 11,409
  • 5
  • 43
  • 82