Get VirtualFile from Editor
已回答
This is a follow up to a question I asked here: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360002766519-Get-Editor-position-index-on-screen
I have a list of visible Editors. I'd like to determine what VirtualFile each of these editors is displaying. How can this be done?
请先登录再写评论。
http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/virtual_file.html#how-do-i-get-a-virtual-file
Excellent! How about setting the VirtualFile being displayed in a currently visible Editor (not necessarily selected editor), or replacing a specific Editor with a new one showing a specific VirtualFile?
This is not quite possible. Could you please explain the use-case/workflow for this "exchange of editor contents"?
Sure. For any given editor index > 0 (where there are more than 1 editors open), the user can select to "follow" the 1st editor.
- "1st editor" = top-leftmost editor.
- "Counterparts" = corresponding c/cpp header and source files. "example.h" and "example.cpp" are counterparts.
- "Following editor" = editor that automatically shows 1st editor's counterpart.
Consider these examples:
Example 1:
- There are two editors, Editor1 and Editor2.
- Editor2 is set to "follow" Editor1.
- Editor1 is showing FileA.h and Editor2 is showing FileA.cpp
- The user changes Editor1 to show FileB.h -> Editor2 automatically switches to showing FileB.cpp
Example 2:
- There are four editors, Editor1, 2, 3 and 4.
- Editor3 is set to "follow" Editor1.
- Editor1 is showing FileX.cpp and Editor3 is showing FileX.h
- The user changes Editor1 to show FileY.cpp -> Editor3 automatically switches to showing FileY.h
- Editor2 and 4 are left unchanged.
So the plugin needs to be able to say "replace arbitrary editor S with editor T [showing some new file]."
Not getting into the why or if there is a better way to achieve this.
I think this topic can help. It reloads editors for a different reason but does preserve the layout and pinned status of the editors so you can use it as a staring point: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360001940480-How-to-close-reopen-an-editor-while-preserving-its-position-in-split-panes-?page=1#community_comment_360000286660
When you reload editors you can change the virtual file when opening the editor since a new editor is opened for the file in all cases.
Thanks for detailed samples. Vladimir's sample might indeed be a solution.
Another approach might be to provide your custom Editor component that simply holds the two related files in separate editors "together", so you'll have full control over synchronizing the two contents. See org.jetbrains.idea.devkit.testAssistant.TestDataGroupFileEditor in Plugin Devkit as sample.
I forgot to mention that
EditorWindow.INITIAL_INDEX_KEY
went package private between 2016/10 and 2018/06 in the API.I use a class which is instantiated once in the project component to wrap the key. Reflection will be used if getting it nicely does not work.
The code from above:
file.putUserData(EditorWindow.INITIAL_INDEX_KEY, editorIndex)
changes toINITIAL_INDEX_KEY.setEditorWindowInitialIndex(file, editorIndex)
.Thanks for the info, looks very promising.
I'm having a Java Newbie issue. IntelliJ is not recognizing the 'companion' 'val' or 'lazy' keywords in:
I've set the project and module SDK to OpenJDK 11 and language level 11.
That is Kotlin, not Java code.
Hah! Wow, they look similar.
That is because it is Kotlinnot Java.
Java equivalent but without the lazy initialization would be:
Yes, Kotlin runs on JVM and is Java compatible but so much more expressive.
I am converting everything that I can to Kotlin in my plugin.
Thanks for the info.
In my case this was actually pretty easy since I don't use tabs. I just keep a list of open editors (one Editor per EditorWindow) and their positions on screen. When an editor changes I compare the old order, new order and changed editor, figure out what editors I actually want and in what order I want them in, and then close all open editors (minus a dummy file) and re-open in the desired editors in the desired order. Surprisingly it all happens pretty much instantaneously.
This brings me to my next question -- is it possible to force the Settings -> Editor -> General -> Editor Tabs -> Placement: None option from within my plugin? I'm wiring the plugin for my own use, but if it can be reasonably easily made to play nice with an out-of-the-box CLion installation I might as well post it up on the Marketplace.
com.intellij.ide.ui.UISettings#setEditorTabPlacement using UISettings.TABS_NONE. But please make sure user confirms this choice before applying automatically.
Nice and simple.
Is there a standard way of presenting a confirmation modal dialog to the user?
com.intellij.openapi.ui.Messages#showYesNoDialog
Closing all editors and re-opening them is turning out to be quite snow in practice (outside my simple test project using small one-liner files) and causes an annoying flickering effect.
What would really be great is to be able to "intercept" the user's attempt to open a file, whether that action originates from them clicking an item in the Project tool window, or selecting a file from the Navigation Bar, or what-have-you. The plugin could see that the user was trying to open file X, and decide what window to load it in. Or perhaps equivalent would be the ability to "veto" when the IDE is trying to open a file in response to a user action. Right now I'm using EditorFactoryListener.editorCreate() to figure out when the user opens a file, but at that point the Editor is already in the process or being displayed, and its destination EditorWindow has already been chosen. Can these user actions be intercepted and/or canceled before an Editor is actually created?
While you could intercept some "known" ways of opening files, I doubt it will be possible to catch all ways completely - and any 3rd party plugin could add new ways of opening editors. There is no "earlier" way than using com.intellij.openapi.editor.event.EditorFactoryListener#editorCreated