Skip to content

Commit ba6f48f

Browse files
committed
feat: folding and scrolling behavior
1 parent a9549fd commit ba6f48f

File tree

4 files changed

+131
-49
lines changed

4 files changed

+131
-49
lines changed

src/main/kotlin/com/github/xepozz/php_dump/panel/OpcodesTerminalPanel.kt

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import com.github.xepozz.php_dump.actions.OpenPhpSettingsAction
55
import com.github.xepozz.php_dump.actions.RefreshAction
66
import com.github.xepozz.php_dump.configuration.PhpDumpSettingsService
77
import com.github.xepozz.php_dump.configuration.PhpOpcacheDebugLevel
8+
import com.github.xepozz.php_dump.services.EditorProvider
89
import com.github.xepozz.php_dump.services.OpcodesDumperService
9-
import com.github.xepozz.php_opcodes_language.language.PHPOpFileType
1010
import com.intellij.icons.AllIcons
1111
import com.intellij.openapi.Disposable
1212
import com.intellij.openapi.actionSystem.ActionManager
@@ -17,15 +17,12 @@ import com.intellij.openapi.actionSystem.DefaultActionGroup
1717
import com.intellij.openapi.application.EDT
1818
import com.intellij.openapi.command.WriteCommandAction
1919
import com.intellij.openapi.editor.EditorFactory
20-
import com.intellij.openapi.editor.ex.EditorEx
2120
import com.intellij.openapi.fileChooser.FileChooser
2221
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
2322
import com.intellij.openapi.fileEditor.FileEditorManager
2423
import com.intellij.openapi.project.Project
2524
import com.intellij.openapi.ui.SimpleToolWindowPanel
2625
import com.intellij.psi.PsiDocumentManager
27-
import com.intellij.psi.PsiManager
28-
import com.intellij.testFramework.LightVirtualFile
2926
import com.jetbrains.php.lang.PhpFileType
3027
import kotlinx.coroutines.CoroutineScope
3128
import kotlinx.coroutines.Dispatchers
@@ -40,48 +37,24 @@ import javax.swing.JPanel
4037
class OpcodesTerminalPanel(
4138
val project: Project,
4239
) : SimpleToolWindowPanel(false, false), RefreshablePanel, Disposable {
40+
4341
val fileEditorManager = FileEditorManager.getInstance(project)
4442
val documentManager = PsiDocumentManager.getInstance(project)
43+
val editorFactory = EditorFactory.getInstance()
4544

4645
private val service = project.getService(OpcodesDumperService::class.java)
46+
private val editorProvider = project.getService(EditorProvider::class.java)
4747
private val state = PhpDumpSettingsService.getInstance(project)
48-
private val editorFactory: EditorFactory = EditorFactory.getInstance()
49-
50-
private val virtualFile: LightVirtualFile = LightVirtualFile(
51-
"opcodes.phpop",
52-
PHPOpFileType.INSTANCE,
53-
""
54-
)
55-
val psiFile = PsiManager.getInstance(project).findFile(virtualFile)!!
56-
val document = documentManager.getDocument(psiFile)!!
57-
58-
private var editor = editorFactory.createEditor(
59-
document,
60-
project,
61-
virtualFile,
62-
false
63-
) as EditorEx
48+
49+
val editor = editorProvider.getOrCreateEditor()
6450
val viewComponent = editor.component
6551

6652
init {
67-
configureEditor()
53+
6854
createToolBar()
6955
createContent()
7056
}
7157

72-
private fun configureEditor() {
73-
editor.settings.apply {
74-
isBlinkCaret = true
75-
isCaretRowShown = true
76-
isBlockCursor = false
77-
isLineMarkerAreaShown = true
78-
isAutoCodeFoldingEnabled = true
79-
isSmartHome = true
80-
isShowIntentionBulb = true
81-
}
82-
83-
editor.setCaretEnabled(true)
84-
}
8558

8659
private fun createToolBar() {
8760
val actionGroup = DefaultActionGroup().apply {
@@ -207,8 +180,8 @@ class OpcodesTerminalPanel(
207180

208181
private fun setDocumentText(project: Project, content: String) {
209182
WriteCommandAction.runWriteCommandAction(project) {
210-
document.setText(content)
211-
documentManager.commitDocument(document)
183+
editor.document.setText(content)
184+
documentManager.commitDocument(editor.document)
212185
}
213186
}
214187

src/main/kotlin/com/github/xepozz/php_dump/panel/TokenTreePanel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class TokenTreePanel(private val project: Project) :
108108
}
109109
}
110110

111-
private fun navigation(closestPathForLocation: TreePath?) {
111+
private fun navigation(closestPathForLocation: TreePath) {
112112
val lastUserObject = TreeUtil.getLastUserObject(closestPathForLocation)
113113
if (lastUserObject is TokenNode) {
114114
val fileEditor = FileEditorManager.getInstance(project)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.github.xepozz.php_dump.services
2+
3+
import com.github.xepozz.php_opcodes_language.language.PHPOpFileType
4+
import com.intellij.openapi.components.Service
5+
import com.intellij.openapi.editor.EditorFactory
6+
import com.intellij.openapi.editor.ex.EditorEx
7+
import com.intellij.openapi.project.Project
8+
import com.intellij.openapi.util.Key
9+
import com.intellij.psi.PsiDocumentManager
10+
import com.intellij.psi.PsiManager
11+
import com.intellij.testFramework.LightVirtualFile
12+
13+
@Service(Service.Level.PROJECT)
14+
class EditorProvider(var project: Project) {
15+
companion object {
16+
val editorId = Key.create<Boolean>("opcodes.editor.id")
17+
}
18+
19+
val documentManager = PsiDocumentManager.getInstance(project)
20+
val editorFactory = EditorFactory.getInstance()
21+
22+
var editor: EditorEx? = null
23+
24+
fun getOrCreateEditor(): EditorEx = synchronized(this) {
25+
editor?.let { return it }
26+
27+
val virtualFile = LightVirtualFile(
28+
"opcodes.phpop",
29+
PHPOpFileType.INSTANCE,
30+
""
31+
)
32+
val psiFile = PsiManager.getInstance(project).findFile(virtualFile)!!
33+
val document = documentManager.getDocument(psiFile)!!
34+
35+
return@synchronized (editorFactory.createEditor(document, project, virtualFile, false) as EditorEx)
36+
.apply {
37+
settings.apply {
38+
isBlinkCaret = true
39+
isCaretRowShown = true
40+
isBlockCursor = false
41+
isLineMarkerAreaShown = true
42+
isAutoCodeFoldingEnabled = true
43+
isSmartHome = true
44+
isShowIntentionBulb = true
45+
}
46+
47+
setCaretEnabled(true)
48+
putUserData(editorId, true)
49+
50+
editor = this
51+
}
52+
}
53+
}
Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,85 @@
11
package com.github.xepozz.php_dump.startup
22

3+
import com.github.xepozz.php_dump.services.EditorProvider
4+
import com.github.xepozz.php_opcodes_language.language.PHPOpFile
5+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpBlockName
6+
import com.intellij.openapi.editor.ScrollType
37
import com.intellij.openapi.editor.event.EditorMouseEvent
48
import com.intellij.openapi.editor.event.EditorMouseListener
9+
import com.intellij.openapi.project.Project
510
import com.intellij.psi.PsiDocumentManager
11+
import com.intellij.psi.util.PsiTreeUtil
12+
import com.intellij.psi.util.endOffset
13+
import com.intellij.psi.util.startOffset
14+
import com.jetbrains.php.lang.psi.elements.Method
15+
616

717
class EditorListener : EditorMouseListener {
818
override fun mouseClicked(event: EditorMouseEvent) {
919
val editor = event.editor
1020
val project = editor.project ?: return
11-
val priDocumentManager = PsiDocumentManager.getInstance(project)
12-
val psiFile = priDocumentManager.getPsiFile(editor.document)
21+
val psiDocumentManager = PsiDocumentManager.getInstance(project)
22+
val psiFile = psiDocumentManager.getPsiFile(editor.document)
1323
val offset = editor.logicalPositionToOffset(event.logicalPosition)
1424
val element = psiFile?.findElementAt(offset) ?: return
1525

16-
println("clicked on $element")
26+
val method = PsiTreeUtil.getParentOfType(element, Method::class.java) ?: return
27+
28+
highlightElement(project, psiDocumentManager, method)
29+
}
30+
31+
private fun highlightElement(
32+
project: Project,
33+
psiDocumentManager: PsiDocumentManager,
34+
method: Method
35+
) {
36+
val editorProvider = project.getService(EditorProvider::class.java)
37+
val opcodesEditor = editorProvider.getOrCreateEditor()
38+
39+
val psiFile = psiDocumentManager.getPsiFile(opcodesEditor.document) as? PHPOpFile ?: return
40+
41+
PsiTreeUtil.findChildrenOfType(psiFile, PHPOpBlockName::class.java)
42+
.firstOrNull { it.methodName?.name == method.name }
43+
?.let {
44+
opcodesEditor.scrollingModel.scrollTo(
45+
opcodesEditor.offsetToLogicalPosition(it.textOffset), ScrollType.CENTER_DOWN
46+
)
47+
48+
val block = it.parent
1749

18-
// val toolWindowManager = ToolWindowManager.getInstance(project)
19-
// val toolWindow = toolWindowManager.getToolWindow("PHP Dump")
20-
//
21-
// toolWindow
22-
// ?.component
23-
// ?.components
24-
// ?.mapNotNull { it as? RefreshablePanel }
25-
// ?.forEach { it.refresh(project, RefreshType.AUTO) }
26-
// ?: return
50+
// opcodesEditor.markupModel.apply {
51+
// removeAllHighlighters()
52+
// addRangeHighlighter(
53+
// block.startOffset,
54+
// block.endOffset,
55+
// 0,
56+
// TextAttributes().apply {
57+
// effectType = EffectType.BOXED
58+
// effectColor = JBColor.RED
59+
// },
60+
// HighlighterTargetArea.EXACT_RANGE,
61+
// )
62+
// }
2763

64+
opcodesEditor.foldingModel.apply {
65+
runBatchFoldingOperation {
66+
clearFoldRegions()
67+
createFoldRegion(
68+
0,
69+
block.startOffset - 1,
70+
"...",
71+
null,
72+
true,
73+
)
74+
createFoldRegion(
75+
block.endOffset,
76+
block.containingFile.textLength,
77+
"...",
78+
null,
79+
true,
80+
)
81+
}
82+
}
83+
}
2884
}
2985
}

0 commit comments

Comments
 (0)