Skip to content

Commit e4ebf1c

Browse files
committed
feat(run): 运行输出支持过滤(仅显示含关键字的行)
控制台头部新增过滤开关,展开后输入关键字仅渲染匹配行并显示行数; 不影响原始输出与复制。
1 parent d3cb43b commit e4ebf1c

3 files changed

Lines changed: 46 additions & 3 deletions

File tree

src/components/ConsoleOutput.vue

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
<div class="flex items-center space-x-3">
1313
<span v-if="isCopied" class="text-xs text-gray-400">{{ t('console.copied') }}</span>
1414

15+
<!-- 过滤按钮 -->
16+
<button v-if="output"
17+
@click="showFilter = !showFilter"
18+
class="text-gray-400 hover:text-white transition-colors duration-200 p-1 rounded hover:bg-gray-700 cursor-pointer"
19+
:class="{ 'text-white bg-gray-700': showFilter }"
20+
:title="t('console.filterTitle')">
21+
<Search class="w-3 h-3"/>
22+
</button>
23+
1524
<!-- 复制按钮 -->
1625
<button v-if="output && !isRunning"
1726
@click="copyOutput"
@@ -35,6 +44,15 @@
3544
</div>
3645
</div>
3746

47+
<!-- 过滤栏:仅显示包含关键字的行 -->
48+
<div v-if="showFilter && output" class="px-2 py-1 border-b border-gray-700 flex items-center gap-2">
49+
<Search class="w-3 h-3 text-gray-500 flex-shrink-0"/>
50+
<input v-model="filterQuery"
51+
class="flex-1 bg-transparent text-xs text-gray-200 placeholder-gray-600 focus:outline-none"
52+
:placeholder="t('console.filterPlaceholder')"/>
53+
<span v-if="filterQuery.trim()" class="text-[10px] text-gray-500 flex-shrink-0">{{ t('console.filterCount', { n: matchCount }) }}</span>
54+
</div>
55+
3856
<div class="flex-1 overflow-auto" ref="outputContainer">
3957
<div v-if="isRunning && !output" class="p-4 flex items-center space-x-2 text-yellow-400">
4058
<Loader class="w-4 h-4 animate-spin"/>
@@ -63,7 +81,7 @@
6381
<script setup lang="ts">
6482
import { computed, nextTick, ref, watch } from 'vue'
6583
import { useI18n } from 'vue-i18n'
66-
import { Check, Clock, Copy, Loader, Terminal, Trash2 } from 'lucide-vue-next'
84+
import { Check, Clock, Copy, Loader, Search, Terminal, Trash2 } from 'lucide-vue-next'
6785
import { ansiToHtml } from '../utils/ansi'
6886
6987
const props = defineProps<{
@@ -81,12 +99,31 @@ const {t} = useI18n()
8199
const isCopied = ref(false)
82100
const outputContainer = ref<HTMLElement>()
83101
102+
// 输出过滤:仅显示包含关键字的行
103+
const showFilter = ref(false)
104+
const filterQuery = ref('')
105+
const filteredText = computed(() => {
106+
const q = filterQuery.value.trim().toLowerCase()
107+
const text = props.output || ''
108+
if (!showFilter.value || !q) {
109+
return text
110+
}
111+
return text.split('\n').filter(l => l.toLowerCase().includes(q)).join('\n')
112+
})
113+
const matchCount = computed(() => {
114+
const q = filterQuery.value.trim()
115+
if (!q) {
116+
return 0
117+
}
118+
return filteredText.value ? filteredText.value.split('\n').length : 0
119+
})
120+
84121
// 动态切换图标
85122
const copyIcon = computed(() => isCopied.value ? Check : Copy)
86123
87124
// 根据执行状态和成功状态确定输出样式
88-
// 渲染 ANSI 颜色(自带 HTML 转义)
89-
const renderedOutput = computed(() => ansiToHtml(props.output || ''))
125+
// 渲染 ANSI 颜色(自带 HTML 转义);过滤开启时仅渲染匹配行
126+
const renderedOutput = computed(() => ansiToHtml(filteredText.value))
90127
91128
const getOutputClass = () => {
92129
if (props.isRunning) {

src/i18n/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,9 @@
819819
"copyFailed": "Copy failed",
820820
"copyTitle": "Copy output",
821821
"clearTitle": "Clear console",
822+
"filterTitle": "Filter output",
823+
"filterPlaceholder": "Filter lines containing…",
824+
"filterCount": "{n} lines",
822825
"ms": "{n} ms",
823826
"executing": "Running code...",
824827
"programRunning": "Program is running...",

src/i18n/locales/zh-CN.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,9 @@
819819
"copyFailed": "复制失败",
820820
"copyTitle": "复制输出内容",
821821
"clearTitle": "清空控制台",
822+
"filterTitle": "过滤输出",
823+
"filterPlaceholder": "过滤包含关键字的行…",
824+
"filterCount": "{n} 行",
822825
"ms": "{n} 毫秒",
823826
"executing": "执行代码中...",
824827
"programRunning": "程序正在运行...",

0 commit comments

Comments
 (0)