From a VS2008 VSPackage, how do I get notified whenever caret position changed?
Asked Answered
G

2

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.

Goldschmidt answered 15/5, 2013 at 6:3 Comment(5)
Do you have a IVsTextView reference available?Silhouette
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.Goldschmidt
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.Silhouette
@SimonMourier Well, there must be some way, as there are many extensions (Resharper, CodeRush) that work in VS2008 and react to each caret move.Goldschmidt
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.Silhouette
G
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

Goldschmidt answered 24/5, 2013 at 9:52 Comment(0)
D
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
   }
}
Dextrosinistral answered 23/5, 2013 at 13:38 Comment(3)
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!Goldschmidt
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) => Dextrosinistral
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).Goldschmidt
G
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

Goldschmidt answered 24/5, 2013 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.