Skip to content

Commit 23f41bc

Browse files
committed
feat(markdown): add Markdown preview support
Introduce MarkdownPreviewSketchProvider and MarkdownPreviewHighlightSketch for rendering Markdown content. Remove redundant Markdown preview logic from CodeHighlightSketch and refactor TextBlockView to use MarkdownViewer's base component.
1 parent ef1f6b7 commit 23f41bc

File tree

7 files changed

+78
-36
lines changed

7 files changed

+78
-36
lines changed

core/src/223/main/resources/META-INF/autodev-core.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.patch.DiffLangSketchProvider"/>
254254
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.webview.WebpageSketchProvider"/>
255255
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.openapi.OpenAPISketchProvider"/>
256+
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.MarkdownPreviewSketchProvider"/>
256257

257258
<toolchainFunctionProvider implementation="cc.unitmesh.devti.bridge.archview.ComponentViewFunctionProvider"/>
258259
<toolchainFunctionProvider implementation="cc.unitmesh.devti.bridge.archview.ContainerViewFunctionProvider"/>

core/src/233/main/kotlin/com/intellij/temporary/gui/block/TextBlockView.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import cc.unitmesh.devti.gui.chat.message.ChatRole
55
import cc.unitmesh.devti.sketch.ui.code.MarkdownViewer
66
import cc.unitmesh.devti.util.parser.convertMarkdownToHtml
77
import com.intellij.ide.BrowserUtil
8-
import com.intellij.openapi.util.text.StringUtil
98
import com.intellij.util.ui.ExtendableHTMLViewFactory
10-
import com.intellij.util.ui.HTMLEditorKitBuilder
119
import com.intellij.xml.util.XmlStringUtil
1210
import java.awt.Component
1311
import java.awt.event.MouseAdapter
1412
import java.awt.event.MouseEvent
1513
import javax.swing.JEditorPane
1614
import javax.swing.SizeRequirements
1715
import javax.swing.event.HyperlinkEvent
18-
import javax.swing.text.DefaultCaret
1916
import javax.swing.text.Element
2017
import javax.swing.text.View
2118
import javax.swing.text.html.ParagraphView
@@ -41,7 +38,7 @@ class TextBlockView(private val block: MessageBlock) : MessageBlockView {
4138
override fun getComponent(): Component = component
4239

4340
private fun createComponent(): JEditorPane {
44-
val jEditorPane = createBaseComponent()
41+
val jEditorPane = MarkdownViewer.createBaseComponent()
4542
jEditorPane.addHyperlinkListener {
4643
if (it.eventType == HyperlinkEvent.EventType.ACTIVATED) {
4744
BrowserUtil.browse(it.url)
@@ -63,10 +60,6 @@ class TextBlockView(private val block: MessageBlock) : MessageBlockView {
6360

6461
return XmlStringUtil.escapeString(txt)
6562
}
66-
67-
companion object {
68-
fun createBaseComponent(): JEditorPane = MarkdownViewer.createBaseComponent()
69-
}
7063
}
7164

7265

core/src/233/main/resources/META-INF/autodev-core.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@
254254
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.patch.DiffLangSketchProvider"/>
255255
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.webview.WebpageSketchProvider"/>
256256
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.openapi.OpenAPISketchProvider"/>
257+
<langSketchProvider implementation="cc.unitmesh.devti.sketch.ui.MarkdownPreviewSketchProvider"/>
257258

258259
<toolchainFunctionProvider implementation="cc.unitmesh.devti.bridge.archview.ComponentViewFunctionProvider"/>
259260
<toolchainFunctionProvider implementation="cc.unitmesh.devti.bridge.archview.ContainerViewFunctionProvider"/>

core/src/main/kotlin/cc/unitmesh/devti/sketch/SketchToolWindow.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import cc.unitmesh.devti.inline.fullWidth
1212
import cc.unitmesh.devti.sketch.ui.ExtensionLangSketch
1313
import cc.unitmesh.devti.sketch.ui.LangSketch
1414
import cc.unitmesh.devti.sketch.ui.LanguageSketchProvider
15+
import cc.unitmesh.devti.sketch.ui.MarkdownPreviewHighlightSketch
1516
import cc.unitmesh.devti.sketch.ui.code.CodeHighlightSketch
1617
import cc.unitmesh.devti.util.AutoDevCoroutineScope
1718
import cc.unitmesh.devti.util.parser.CodeFence
@@ -40,9 +41,6 @@ import kotlinx.coroutines.launch
4041
import org.jetbrains.annotations.NonNls
4142
import java.awt.BorderLayout
4243
import java.awt.Dimension
43-
import java.awt.GradientPaint
44-
import java.awt.Graphics
45-
import java.awt.Graphics2D
4644
import java.awt.Toolkit
4745
import java.awt.datatransfer.StringSelection
4846
import java.awt.event.KeyAdapter
@@ -310,6 +308,12 @@ open class SketchToolWindow(
310308
?.create(project, codeFence.text)
311309
}
312310

311+
val isCanHtml =
312+
codeFence.language == PlainTextLanguage.INSTANCE || codeFence.language.displayName.lowercase() == "markdown"
313+
if (isCanHtml && codeFence.isComplete && blockViews[index] !is ExtensionLangSketch) {
314+
langSketch = MarkdownPreviewHighlightSketch(project, codeFence.text)
315+
}
316+
313317
if (langSketch != null) {
314318
val oldComponent = blockViews[index]
315319
blockViews[index] = langSketch
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package cc.unitmesh.devti.sketch.ui
2+
3+
import cc.unitmesh.devti.fullWidth
4+
import cc.unitmesh.devti.sketch.ui.code.MarkdownViewer
5+
import cc.unitmesh.devti.util.parser.convertMarkdownToHtml
6+
import com.intellij.ide.BrowserUtil
7+
import com.intellij.lang.Language
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.ui.dsl.builder.panel
10+
import java.awt.event.MouseAdapter
11+
import java.awt.event.MouseEvent
12+
import javax.swing.JComponent
13+
import javax.swing.event.HyperlinkEvent
14+
15+
class MarkdownPreviewHighlightSketch(val project: Project, var text: String) : ExtensionLangSketch {
16+
override fun getExtensionName(): String = "Markdown Highlight"
17+
override fun getViewText(): String = text
18+
19+
private val editorPane = MarkdownViewer.createBaseComponent().apply {
20+
addHyperlinkListener {
21+
if (it.eventType == HyperlinkEvent.EventType.ACTIVATED) {
22+
BrowserUtil.browse(it.url)
23+
}
24+
}
25+
addMouseListener(object : MouseAdapter() {
26+
override fun mouseClicked(e: MouseEvent?) {
27+
if (e == null) return
28+
parent?.dispatchEvent(e)
29+
}
30+
})
31+
}
32+
33+
val previewPanel = panel {
34+
row {
35+
cell(editorPane).fullWidth()
36+
}.resizableRow()
37+
}.apply {
38+
border = javax.swing.BorderFactory.createEmptyBorder(8, 8, 8, 8)
39+
}
40+
41+
override fun updateViewText(text: String, complete: Boolean) {
42+
editorPane.text = convertMarkdownToHtml(text)
43+
editorPane.invalidate()
44+
editorPane.repaint()
45+
this.text = text
46+
}
47+
48+
override fun getComponent(): JComponent {
49+
return previewPanel
50+
}
51+
52+
override fun updateLanguage(language: Language?, originLanguage: String?) {}
53+
54+
override fun dispose() {
55+
}
56+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package cc.unitmesh.devti.sketch.ui
2+
3+
import com.intellij.openapi.project.Project
4+
5+
class MarkdownPreviewSketchProvider : LanguageSketchProvider {
6+
override fun isSupported(lang: String): Boolean {
7+
return lang.lowercase() == "markdown"
8+
}
9+
10+
override fun create(project: Project, content: String): ExtensionLangSketch = MarkdownPreviewHighlightSketch(project, content)
11+
}

core/src/main/kotlin/cc/unitmesh/devti/sketch/ui/code/CodeHighlightSketch.kt

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,7 @@ open class CodeHighlightSketch(
7979
if (hasSetupAction) return
8080
hasSetupAction = true
8181

82-
val shouldBeMarkdownView =
83-
(ideaLanguage == null) || ideaLanguage == PlainTextLanguage.INSTANCE || ideaLanguage?.displayName == "Markdown"
84-
val editor = if (shouldBeMarkdownView) {
85-
createMarkdownPreviewEditor(text) ?: createCodeViewerEditor(project, text, ideaLanguage, fileName, this)
86-
} else {
87-
createCodeViewerEditor(project, text, ideaLanguage, fileName, this)
88-
}
82+
val editor = createCodeViewerEditor(project, text, ideaLanguage, fileName, this)
8983

9084
border = JBEmptyBorder(8)
9185
layout = BorderLayout(JBUI.scale(8), 0)
@@ -107,24 +101,6 @@ open class CodeHighlightSketch(
107101
}
108102
}
109103

110-
private fun createMarkdownPreviewEditor(text: String): EditorEx? {
111-
val editorProvider =
112-
FileEditorProvider.EP_FILE_EDITOR_PROVIDER.extensionList.firstOrNull {
113-
it.javaClass.simpleName == "MarkdownSplitEditorProvider"
114-
}
115-
116-
val file = LightVirtualFile(AutoDevSnippetFile.naming("md"), text)
117-
val createEditor = editorProvider?.createEditor(project, file)
118-
119-
val preview = createEditor as? TextEditorWithPreview ?: return null
120-
var editor = preview?.editor as? EditorEx ?: return null
121-
configEditor(editor, project, file, false)
122-
// previewEditor = preview.previewEditor
123-
// previewEditor?.component?.isOpaque = true
124-
// previewEditor?.component?.minimumSize = JBUI.size(0, 0)
125-
return editor
126-
}
127-
128104
override fun getViewText(): String {
129105
return editorFragment?.editor?.document?.text ?: ""
130106
}

0 commit comments

Comments
 (0)