Access Editor object from Documentation Provider

Hello,

I implemented a DocumentationProvider by extending the AbstractDocumentationProvider. Somewhere down the line I need to look up where the current cursor is, as I want to show the type of the element under the cursor. To achieve this I look up the text editor, get the selection model and the start and end position of that selection model. The editor I try to find through

 
FileEditorManager fileEditorManager = FileEditorManager.getInstance(
        project);
 
fileEditorManager.getSelectedTextEditor();

This seems to work, but I keep on getting a rather big stack trace, starting with Access is allowed from event dispatch thread only.
Okay, with what I know about Swing and Intellij, I understand that I am apparently not on the UI thread and need to be on the UI thread to execute this. So, I try to wrap the invocation of the function that contains fileEditorManager.getselectedtextEditor() in ApplicationManager.getApplication().invokeAndWait. But now I seem to get a little smaller stack trace, stating that 'Calling invokeAndWait from read-action leads to possible deadlock. '.

What does not seem to give stack traces is when I wrap the computation in a ApplicationManager.getApplication().invokeLater, but the thing is that that function is asynchronous, so then I don't see an easy way of returning the result, without resorting to thread synchronization primitives.

Can somebody point me in the correct direction for this?

Kasper

6 comments
Comment actions Permalink

Most DocumentationProvider methods receive 'originalElement' argument of type PsiElement, which is exactly the element under caret in editor. Why cannot you use that?

0
Comment actions Permalink

Well, because I want to reuse the functionality for showing the type to bind to an action, a normal keystroke. So, like the scala plugin for example, Alt - = will show the type, and Ctrl - Q will show the same in the documentation provider (which would also contain the type and as such call the same typeInfo function). Using the original psi element would mean I need two separate code paths (or a lot smaller common path, anyway) to decide which psi element needs to get its type resolved (because the action doesn't get this info).
It's possible of course, I'm not saying that, but I was hoping it could be done the way I propose as well.

I take it your answer means that there is no other feasible way of doing this? If so, what's then the best way of finding the line and column number of the psi element under the cursor? Will I not need the Editor for that, anyway (and get into the same problem again)?

0
Comment actions Permalink

There may be no editor and no cursor. For example, the quick documentation action can be invoked from the project view. If you then try to get the selected editor and the data from there, you'll get data for a completely unrelated PSI element.

In an action, if you do have an editor in the data context, you can determine the PSI element that you need to operate on by calling TargetElementUtil.findTargetElement().

0
Comment actions Permalink

Hmm, are you now basically saying that it's a bad idea to show that type information in the documentation provider screen as it might be actually impossible to do so? (fair enough, you know, just trying to get it more or less clear, if it's a bad plan, it's a bad plan and I don't do it anymore, an action is enough in the end).

0
Comment actions Permalink

No. You can show the type information, but you need to calculate it based on the element passed to the documentation provider, not based on the element selected in any editor.

0
Comment actions Permalink

Alright, it took me some time to figure out how to determine the line and column numbers of a psi element (I do that through the Document, functions getLineNumber and getLineStartOffset) but now it indeed seems to work for the documentation provider. The action 'type info' still uses the editor, because over there I need to take into account selections of text, and that seems to have to be done through the Editor's getSelectionModel. So a bit different code paths for both, but it seems to work fine. Thanks for the help!

0

Please sign in to leave a comment.