Skip to content

Commit bae00c6

Browse files
committed
fix(sketch): improve file path extraction in markdown tables #465
Enhances the regex and logic for extracting file paths from backticked markdown content, supporting more path formats and ensuring correct file detection. Also adjusts UI for file open button and PlantUML diagram sizing.
1 parent 8267516 commit bae00c6

File tree

2 files changed

+39
-28
lines changed

2 files changed

+39
-28
lines changed

mpp-ui/src/jvmMain/kotlin/cc/unitmesh/devins/ui/compose/sketch/MarkdownTableRenderer.kt

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.compose.ui.unit.Dp
2222
import androidx.compose.ui.unit.dp
2323
import androidx.compose.ui.unit.times
2424
import cc.unitmesh.devins.ui.compose.icons.AutoDevComposeIcons
25+
import cc.unitmesh.devins.ui.platform.FileChooser
2526
import com.mikepenz.markdown.annotator.AnnotatorSettings
2627
import com.mikepenz.markdown.annotator.annotatorSettings
2728
import com.mikepenz.markdown.annotator.buildMarkdownAnnotatedString
@@ -158,7 +159,10 @@ fun MarkdownTableHeader(
158159
modifier = Modifier.widthIn(tableWidth).height(IntrinsicSize.Max)
159160
) {
160161
header.children.filter { it.type == CELL }.forEachIndexed { idx, cell ->
161-
val weight = if (weights.size == header.children.count { it.type == CELL }) weights[idx] else 1f / (header.children.count { it.type == CELL }).coerceAtLeast(1)
162+
val weight =
163+
if (weights.size == header.children.count { it.type == CELL }) weights[idx] else 1f / (header.children.count { it.type == CELL }).coerceAtLeast(
164+
1
165+
)
162166
Column(
163167
modifier = Modifier.padding(tableCellPadding).weight(weight),
164168
) {
@@ -221,6 +225,19 @@ fun MarkdownTableRow(
221225
val filePath = extractBacktickedPath(raw)
222226
if (filePath != null) {
223227
Row(verticalAlignment = Alignment.CenterVertically) {
228+
IconButton(
229+
modifier = Modifier.size(16.dp),
230+
onClick = {
231+
val root = WorkspaceManager.getCurrentOrEmpty().rootPath
232+
val abs = if (root != null) root + "/" + filePath else filePath
233+
onOpenFile(abs)
234+
}) {
235+
Icon(
236+
modifier = Modifier.size(16.dp),
237+
imageVector = AutoDevComposeIcons.Visibility, contentDescription = "View File"
238+
)
239+
}
240+
Spacer(modifier = Modifier.width(4.dp))
224241
MarkdownTableBasicText(
225242
content = content,
226243
cell = cell,
@@ -229,14 +246,6 @@ fun MarkdownTableRow(
229246
overflow = overflow,
230247
annotatorSettings = annotatorSettings
231248
)
232-
Spacer(modifier = Modifier.width(4.dp))
233-
IconButton(onClick = {
234-
val root = WorkspaceManager.getCurrentOrEmpty().rootPath
235-
val abs = if (root != null) root + "/" + filePath else filePath
236-
onOpenFile(abs)
237-
}) {
238-
Icon(imageVector = AutoDevComposeIcons.Visibility, contentDescription = "View File")
239-
}
240249
}
241250
} else {
242251
MarkdownTableBasicText(
@@ -277,9 +286,23 @@ fun MarkdownTableBasicText(
277286

278287
/**
279288
* Extract backticked file path from markdown cell content
289+
* Supports paths like:
290+
* - `mpp-core/.../CodeReviewArtifact.kt`
291+
* - `src/main/kotlin/MyFile.kt`
292+
* - `path/to/file-name_v2.kt`
280293
*/
281294
private fun extractBacktickedPath(raw: String): String? {
282-
val pathRegex = Regex("`([\\w\\-./]+)`")
295+
// Match backticked content that looks like a file path
296+
// Supports: alphanumeric, dots, slashes, hyphens, underscores, ellipsis (...), brackets, parentheses
297+
val pathRegex = Regex("`([\\w\\-_./@()\\[\\]]+(?:\\.{3})?[\\w\\-_./@()\\[\\]]*)`")
283298
val match = pathRegex.find(raw)
284-
return match?.groupValues?.getOrNull(1)
299+
val candidate = match?.groupValues?.getOrNull(1)
300+
301+
// Filter: must contain at least one slash or a file extension
302+
return if (candidate != null && (candidate.contains('/') || candidate.contains('.'))) {
303+
// Expand ellipsis if present (e.g., mpp-core/.../File.kt -> mpp-core/src/.../File.kt)
304+
candidate
305+
} else {
306+
null
307+
}
285308
}

mpp-ui/src/jvmMain/kotlin/cc/unitmesh/devins/ui/compose/sketch/PlantUmlRenderer.kt

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,10 @@
11
package cc.unitmesh.devins.ui.compose.sketch
22

3-
import androidx.compose.foundation.layout.Box
4-
import androidx.compose.foundation.layout.fillMaxWidth
5-
import androidx.compose.foundation.layout.padding
6-
import androidx.compose.foundation.layout.size
3+
import androidx.compose.foundation.layout.*
74
import androidx.compose.material.icons.Icons
85
import androidx.compose.material.icons.filled.Download
9-
import androidx.compose.material3.CircularProgressIndicator
10-
import androidx.compose.material3.DropdownMenu
11-
import androidx.compose.material3.DropdownMenuItem
12-
import androidx.compose.material3.Icon
13-
import androidx.compose.material3.IconButton
14-
import androidx.compose.material3.Text
15-
import androidx.compose.runtime.Composable
16-
import androidx.compose.runtime.LaunchedEffect
17-
import androidx.compose.runtime.getValue
18-
import androidx.compose.runtime.mutableStateOf
19-
import androidx.compose.runtime.remember
20-
import androidx.compose.runtime.setValue
6+
import androidx.compose.material3.*
7+
import androidx.compose.runtime.*
218
import androidx.compose.ui.Alignment
229
import androidx.compose.ui.Modifier
2310
import androidx.compose.ui.graphics.Color
@@ -105,7 +92,8 @@ fun PlantUmlRenderer(
10592
bitmap = bitmap,
10693
contentDescription = "PlantUML Diagram",
10794
contentScale = ContentScale.Fit,
108-
modifier = Modifier.Companion.fillMaxWidth()
95+
modifier = Modifier.fillMaxWidth()
96+
.widthIn(min = 400.dp)
10997
)
11098

11199
// Download button overlay (always visible)

0 commit comments

Comments
 (0)