Skip to content

Commit 8e13356

Browse files
committed
refactor(structure): enhance structure output formatting #309
1 parent ae8a965 commit 8e13356

File tree

1 file changed

+45
-27
lines changed

1 file changed

+45
-27
lines changed

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/exec/StructureShireCommand.kt

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import com.intellij.lang.LanguageStructureViewBuilder
99
import com.intellij.openapi.application.ApplicationManager
1010
import com.intellij.openapi.application.runReadAction
1111
import com.intellij.openapi.diagnostic.logger
12+
import com.intellij.openapi.editor.Document
1213
import com.intellij.openapi.fileEditor.FileEditor
1314
import com.intellij.openapi.fileEditor.FileEditorManager
1415
import com.intellij.openapi.project.Project
1516
import com.intellij.openapi.vfs.VirtualFile
17+
import com.intellij.psi.PsiDocumentManager
1618
import com.intellij.psi.PsiElement
1719
import com.intellij.psi.PsiFile
1820
import com.intellij.psi.PsiManager
@@ -23,6 +25,14 @@ import kotlinx.coroutines.withContext
2325
class StructureInCommand(val myProject: Project, val prop: String) : InsCommand {
2426
override val commandName: BuiltinCommand = BuiltinCommand.STRUCTURE
2527

28+
/**
29+
* ```
30+
* (1000-9999)
31+
* ```
32+
*/
33+
private val maxLineWith = 11
34+
private val maxDepth = 5
35+
2636
private val logger = logger<StructureInCommand>()
2737
override suspend fun execute(): String? {
2838
val virtualFile = file(myProject, prop)
@@ -43,14 +53,9 @@ class StructureInCommand(val myProject: Project, val prop: String) : InsCommand
4353
}
4454

4555
fun getFileStructure(project: Project, file: VirtualFile, psiFile: PsiFile): String {
46-
var openFiles: Array<FileEditor> = arrayOf()
47-
ApplicationManager.getApplication().invokeAndWait {
48-
openFiles = FileEditorManager.getInstance(myProject).openFile(file, true)
49-
}
50-
51-
val fileEditor = openFiles.firstOrNull() ?: return "No FileEditor found."
52-
5356
val viewFactory = LanguageStructureViewBuilder.INSTANCE.forLanguage(psiFile.language)
57+
val fileEditor: FileEditor = FileEditorManager.getInstance(project).getEditors(file).firstOrNull()
58+
?: return "No FileEditor found."
5459

5560
if (viewFactory != null) {
5661
val view: StructureView = viewFactory.getStructureViewBuilder(psiFile)
@@ -64,36 +69,22 @@ class StructureInCommand(val myProject: Project, val prop: String) : InsCommand
6469
return "No StructureViewModel found."
6570
}
6671

67-
// (1000-9999)
68-
private val maxLineWith = 11
69-
7072
/**
7173
* Display format
7274
* ```
7375
* elementName (location) - line number or navigate to element ?
7476
* ```
7577
*/
7678
private fun traverseStructure(element: StructureViewTreeElement, depth: Int, sb: StringBuilder): StringBuilder {
77-
val indent = if (element.value is PsiElement) {
78-
val psiElement = element.value as PsiElement
79-
val line = "(" + psiElement.textRange.startOffset + "," + psiElement.textRange.endOffset + ")"
80-
if (line.length < maxLineWith) {
81-
line + " ".repeat(maxLineWith - line.length) + " ".repeat(depth)
82-
} else {
83-
line + " ".repeat(depth)
84-
}
85-
} else {
86-
" ".repeat(depth)
87-
}
88-
89-
/// todo: add element line
79+
val indent = formatBeforeCode(element, depth)
9080
var str = element.presentation.presentableText
91-
if (!str.isNullOrBlank() && !element.presentation.locationString.isNullOrBlank()) {
92-
str += " (${element.presentation.locationString})"
81+
// if (!str.isNullOrBlank() && !element.presentation.locationString.isNullOrBlank()) {
82+
// str += " (${element.presentation.locationString})"
83+
// }
84+
if (!str.isNullOrBlank()) {
85+
sb.append(indent).append(str).append("\n")
9386
}
9487

95-
sb.append(indent).append(str).append("\n")
96-
9788
for (child in element.children) {
9889
if (child is StructureViewTreeElement) {
9990
traverseStructure(child, depth + 1, sb)
@@ -103,6 +94,33 @@ class StructureInCommand(val myProject: Project, val prop: String) : InsCommand
10394
return sb
10495
}
10596

97+
private fun formatBeforeCode(element: StructureViewTreeElement, depth: Int): String {
98+
if (depth > maxDepth) {
99+
return " ".repeat(maxLineWith) + " ".repeat(depth)
100+
}
101+
102+
return if (element.value is PsiElement) {
103+
val psiElement = element.value as PsiElement
104+
val line = formatLine(psiElement)
105+
if (line.length < maxLineWith) {
106+
line + " ".repeat(maxLineWith - line.length) + " ".repeat(depth)
107+
} else {
108+
line + " ".repeat(depth)
109+
}
110+
} else {
111+
" ".repeat(maxLineWith) + " ".repeat(depth)
112+
}
113+
}
114+
115+
private fun formatLine(psiElement: PsiElement): String {
116+
val psiFile: PsiFile = psiElement.containingFile
117+
val document: Document = PsiDocumentManager.getInstance(psiFile.project).getDocument(psiFile) ?: return ""
118+
val start = document.getLineNumber(psiElement.textRange.startOffset)
119+
val end = document.getLineNumber(psiElement.textRange.endOffset)
120+
121+
return "(${start + 1}-${end + 1})"
122+
}
123+
106124
fun file(project: Project, path: String): VirtualFile? {
107125
val filename = path.split("#")[0]
108126
val virtualFile = project.lookupFile(filename)

0 commit comments

Comments
 (0)