Get a Tree Node Under Caret
What you should know beforehand:
Examples (?):
Getting a tree node under the current caret position is a very typical task when implementing a navigation or any other tree-node-dependent feature. Actually, there are many ways of obtaining the tree node depending on the context. For example, when implementing context navigation, you can use the GetSelectedTreeNode
method of the IDataContext
object. E.g.:
Nevertheless, if you need a more generic (context-independent) get-node-under-caret function implementation, see the example below:
Notes
The solution component
NodeUnderCaretDetector
has the publicIProperty
-NodeUnderCaret
. You can use this property to obtain the tree node under the caret at any moment of time.The
NodeUnderCaret.Value
is updated each time the caret is moved. This is implemented by means of the legacyCaretMoved
event handler.The
GetTreeNodeUnderCaret()
method performs all the work - it returns theITreeNode
element under the caret.The
textControl
instance (ITextControl
) allows working with the currently opened text file as if you worked with a text editor. Here we obtain the current caret offset by callingtextControl.Caret.Offset()
.Note that, formally speaking,
textControl
knows nothing about the code inside itself - it simply renders the content it gets from anIDocument
instance.By knowing the document, we can obtain the IProjectFile (
_documentManager.TryGetProjectFile
) instance - it provides the API to work with the file's syntax tree.From the
IProjectFile
, we obtain, one after another IPsiSourceFile and IFile (the main element of the PSI syntax tree).IFile
provides theFindNodeAt()
method that returns the node by the specified range.Note that to prevent conflicts with user input, we must obtain the read lock before calculating the node under the caret. This is done by means of the special method of the
IShellLocks
interface:_shellLocks.QueueReadLock(...)
.