generated from JetBrains/intellij-platform-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(editor): restructure Shire file editor and preview components …
…#157 - Split ShireFileEditor into ShireFileEditor and ShirePreviewEditor for better separation of concerns. - Introduce ShirePreviewEditorProvider for handling preview editor creation. - Simplify toolbar creation and action handling in ShireFileEditor. - Remove unused imports and redundant code.
- Loading branch information
Showing
1 changed file
with
82 additions
and
62 deletions.
There are no files selected for viewing
144 changes: 82 additions & 62 deletions
144
shirelang/src/main/kotlin/com/phodal/shirelang/editor/ShireFileEditorProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,127 +1,147 @@ | ||
package com.phodal.shirelang.editor | ||
|
||
import com.intellij.codeHighlighting.BackgroundEditorHighlighter | ||
import com.intellij.icons.AllIcons | ||
import com.intellij.ide.structureView.StructureViewBuilder | ||
import com.intellij.openapi.actionSystem.* | ||
import com.intellij.openapi.actionSystem.ex.ActionUtil | ||
import com.intellij.openapi.editor.Editor | ||
import com.intellij.openapi.fileEditor.* | ||
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl | ||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider | ||
import com.intellij.openapi.fileTypes.FileTypeRegistry | ||
import com.intellij.openapi.project.DumbAware | ||
import com.intellij.openapi.project.Project | ||
import com.intellij.openapi.util.UserDataHolder | ||
import com.intellij.openapi.util.UserDataHolderBase | ||
import com.intellij.openapi.vfs.VirtualFile | ||
import com.intellij.pom.Navigatable | ||
import com.intellij.psi.PsiManager | ||
import com.intellij.testFramework.LightVirtualFile | ||
import com.intellij.ui.dsl.builder.Align | ||
import com.intellij.ui.dsl.builder.panel | ||
import com.phodal.shirecore.ShireCoroutineScope | ||
import com.phodal.shirelang.ShireFileType | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.launch | ||
import java.awt.BorderLayout | ||
import java.beans.PropertyChangeListener | ||
import javax.swing.JComponent | ||
import javax.swing.JPanel | ||
|
||
class ShireFileEditorProvider : FileEditorProvider, DumbAware { | ||
override fun getEditorTypeId() = "r-editor" | ||
class ShireFileEditorProvider : WeighedFileEditorProvider() { | ||
override fun getEditorTypeId() = "shire-editor" | ||
private val mainProvider: TextEditorProvider = TextEditorProvider.getInstance() | ||
private val previewProvider: FileEditorProvider = ShirePreviewEditorProvider() | ||
|
||
override fun accept(project: Project, file: VirtualFile) = | ||
FileTypeRegistry.getInstance().isFileOfType(file, ShireFileType.INSTANCE) | ||
|
||
override fun createEditor(project: Project, file: VirtualFile): FileEditor { | ||
val editor = TextEditorProvider.getInstance().createEditor(project, file) as TextEditorImpl | ||
val editor = TextEditorProvider.getInstance().createEditor(project, file) | ||
if (editor.file is LightVirtualFile) { | ||
return editor | ||
} | ||
|
||
return ShireFileEditor(project, editor, file) | ||
val mainEditor = mainProvider.createEditor(project, file) as TextEditor | ||
val preview = previewProvider.createEditor(project, file) as ShirePreviewEditor | ||
return ShireFileEditor(mainEditor, preview, project) | ||
} | ||
|
||
override fun getPolicy() = FileEditorPolicy.HIDE_DEFAULT_EDITOR | ||
} | ||
|
||
class ShirePreviewEditorProvider : WeighedFileEditorProvider(), AsyncFileEditorProvider { | ||
override fun accept(project: Project, file: VirtualFile): Boolean { | ||
return FileTypeRegistry.getInstance().isFileOfType(file, ShireFileType.INSTANCE) | ||
} | ||
|
||
override fun createEditor(project: Project, virtualFile: VirtualFile): FileEditor { | ||
return ShirePreviewEditor(project, virtualFile) | ||
} | ||
|
||
override fun getEditorTypeId(): String = "markdown-preview-editor" | ||
|
||
override fun getPolicy(): FileEditorPolicy = FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR | ||
} | ||
|
||
/** | ||
* Display shire file render prompt and have a sample file as view | ||
*/ | ||
open class ShirePreviewEditorProvider : FileEditorProvider, DumbAware { | ||
override fun getEditorTypeId() = "shire-preview" | ||
open class ShirePreviewEditor( | ||
val project: Project, | ||
val virtualFile: VirtualFile, | ||
) : UserDataHolder by UserDataHolderBase(), FileEditor { | ||
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) | ||
private var mainEditor = MutableStateFlow<Editor?>(null) | ||
private val visualPanel: JPanel = JPanel(BorderLayout()).apply { | ||
/// show preview of the shire file | ||
} | ||
|
||
override fun accept(project: Project, file: VirtualFile) = | ||
FileTypeRegistry.getInstance().isFileOfType(file, ShireFileType.INSTANCE) | ||
init { | ||
ShireCoroutineScope.scope(project).launch { | ||
val corePanel = panel { | ||
row { | ||
val textArea = textArea() | ||
textArea.align(Align.FILL) | ||
} | ||
} | ||
|
||
override fun createEditor(project: Project, file: VirtualFile): FileEditor { | ||
val editor = TextEditorProvider.getInstance().createEditor(project, file) as TextEditorImpl | ||
if (editor.file is LightVirtualFile) { | ||
return editor | ||
visualPanel.add(corePanel) | ||
} | ||
} | ||
|
||
|
||
return ShireFileEditor(project, editor, file) | ||
fun setMainEditor(editor: Editor) { | ||
check(mainEditor.value == null) | ||
mainEditor.value = editor | ||
} | ||
|
||
override fun getPolicy() = FileEditorPolicy.HIDE_DEFAULT_EDITOR | ||
override fun getComponent(): JComponent = visualPanel | ||
override fun getName(): String = "Shire Prompt Preview" | ||
override fun setState(state: FileEditorState) {} | ||
override fun isModified(): Boolean = false | ||
override fun isValid(): Boolean = true | ||
override fun getFile(): VirtualFile = virtualFile | ||
override fun getPreferredFocusedComponent(): JComponent? = null | ||
override fun addPropertyChangeListener(listener: PropertyChangeListener) {} | ||
override fun removePropertyChangeListener(listener: PropertyChangeListener) {} | ||
override fun dispose() {} | ||
} | ||
|
||
open class ShireFileEditor( | ||
val project: Project, | ||
val textEditor: TextEditor, | ||
val virtualFile: VirtualFile, | ||
) : UserDataHolderBase(), TextEditor { | ||
protected val mainComponent = JPanel(BorderLayout()) | ||
class ShireFileEditor( | ||
private val ourEditor: TextEditor, | ||
private val preview: ShirePreviewEditor, | ||
private val project: Project, | ||
) : TextEditorWithPreview(ourEditor, preview) { | ||
val virtualFile: VirtualFile = ourEditor.file | ||
|
||
init { | ||
val toolbarComponent = createToolbar().component | ||
mainComponent.add(textEditor.component, BorderLayout.CENTER) | ||
// maybe left panel for editor | ||
/// split for workflow view | ||
mainComponent.add(toolbarComponent, BorderLayout.NORTH) | ||
editor.contentComponent.putClientProperty(ActionUtil.ALLOW_ACTION_PERFORM_WHEN_HIDDEN, true) | ||
preview.setMainEditor(editor) | ||
} | ||
|
||
override fun dispose() { | ||
TextEditorProvider.getInstance().disposeEditor(textEditor) | ||
TextEditorProvider.getInstance().disposeEditor(ourEditor) | ||
} | ||
|
||
private fun createToolbar(): ActionToolbar { | ||
override fun createToolbar(): ActionToolbar { | ||
return ActionManager.getInstance() | ||
.createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, createActionGroup(project, virtualFile, editor), true) | ||
.also { | ||
it.targetComponent = editor.contentComponent | ||
} | ||
} | ||
|
||
private fun createActionGroup(project: Project, report: VirtualFile, editor: Editor): ActionGroup { | ||
private fun createActionGroup(project: Project, virtualFile: VirtualFile, editor: Editor): ActionGroup { | ||
return DefaultActionGroup( | ||
createRunShireAction(project), | ||
createHelpAction(project), | ||
Separator() | ||
) | ||
} | ||
|
||
private fun createRunShireAction(project: Project): AnAction { | ||
val idleIcon = AllIcons.Actions.Execute | ||
return object : AnAction("Run Shire", "Run Shire", idleIcon) { | ||
private fun createHelpAction(project: Project): AnAction { | ||
val idleIcon = AllIcons.Actions.Help | ||
return object : AnAction("Help", "Help", idleIcon) { | ||
override fun actionPerformed(e: AnActionEvent) { | ||
/// run current File | ||
val url = "https://shire.phodal.com/" | ||
com.intellij.ide.BrowserUtil.browse(url) | ||
} | ||
} | ||
} | ||
|
||
override fun getComponent() = mainComponent | ||
override fun getState(level: FileEditorStateLevel): FileEditorState = textEditor.getState(level) | ||
override fun setState(state: FileEditorState) = textEditor.setState(state) | ||
override fun isModified(): Boolean = textEditor.isModified | ||
override fun isValid(): Boolean = textEditor.isValid | ||
override fun getBackgroundHighlighter(): BackgroundEditorHighlighter? = textEditor.backgroundHighlighter | ||
override fun getCurrentLocation(): FileEditorLocation? = textEditor.currentLocation | ||
override fun getPreferredFocusedComponent() = textEditor.preferredFocusedComponent | ||
override fun getName(): String = "Shire Preview" | ||
|
||
override fun getStructureViewBuilder(): StructureViewBuilder? = textEditor.structureViewBuilder | ||
override fun getEditor(): Editor = textEditor.editor | ||
override fun navigateTo(navigatable: Navigatable) = textEditor.navigateTo(navigatable) | ||
override fun canNavigateTo(navigatable: Navigatable): Boolean = textEditor.canNavigateTo(navigatable) | ||
override fun getFile(): VirtualFile = virtualFile | ||
|
||
override fun addPropertyChangeListener(listener: PropertyChangeListener) { | ||
textEditor.addPropertyChangeListener(listener) | ||
} | ||
|
||
override fun removePropertyChangeListener(listener: PropertyChangeListener) { | ||
textEditor.removePropertyChangeListener(listener) | ||
} | ||
} |