Skip to content

Commit e1b6a61

Browse files
committed
feat (core): 支持编辑器显示空格省略配置
1 parent 0b78d70 commit e1b6a61

5 files changed

Lines changed: 135 additions & 2 deletions

File tree

src-tauri/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub struct EditorConfig {
1818
pub font_size: Option<u32>, // 编辑器字体大小
1919
pub show_line_numbers: Option<bool>, // 是否显示行号
2020
pub show_function_help: Option<bool>, // 是否显示函数帮助
21+
pub space_dot_omission: Option<bool>, // 是否显示空格省略
2122
}
2223

2324
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -45,6 +46,7 @@ impl Default for AppConfig {
4546
font_size: Some(14),
4647
show_line_numbers: Some(true),
4748
show_function_help: Some(false),
49+
space_dot_omission: Some(false),
4850
}),
4951
}
5052
}
@@ -103,6 +105,7 @@ impl ConfigManager {
103105
font_size: Some(14),
104106
show_line_numbers: Some(true),
105107
show_function_help: Some(false),
108+
space_dot_omission: Some(false),
106109
});
107110
println!("读取配置 -> 添加默认 editor 配置");
108111
}
@@ -209,6 +212,7 @@ impl ConfigManager {
209212
font_size: Some(14),
210213
show_line_numbers: Some(true),
211214
show_function_help: Some(false),
215+
space_dot_omission: Some(false),
212216
}),
213217
}
214218
}

src/components/setting/Editor.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
<Switch v-model="editorConfig.show_function_help"/>
1313
</Label>
1414

15+
<Label label="是否显示空格省略">
16+
<Switch v-model="editorConfig.space_dot_omission"/>
17+
</Label>
18+
1519
<Label label="缩进空格数">
1620
<Number v-model="editorConfig.tab_size" :min="1" :max="8" placeholder="缩进空格数"/>
1721
</Label>
@@ -27,8 +31,8 @@
2731
</template>
2832

2933
<script setup lang="ts">
30-
import { onMounted } from 'vue'
31-
import { useEditorConfig } from '../../composables/useEditorConfig'
34+
import {onMounted} from 'vue'
35+
import {useEditorConfig} from '../../composables/useEditorConfig'
3236
import Select from '../../ui/Select.vue'
3337
import Switch from '../../ui/Switch.vue'
3438
import Number from '../../ui/Number.vue'

src/composables/useCodeMirrorEditor.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {StreamLanguage} from '@codemirror/language'
6464
import {EditorConfig} from '../types/app.ts'
6565
import {EditorView} from '@codemirror/view'
6666
import {useCodeMirrorFunctionHelp} from './useCodeMirrorFunctionHelp'
67+
import {useCodeMirrorSpaceOmission} from './useCodeMirrorSpaceOmission.ts'
6768

6869
interface Props
6970
{
@@ -234,6 +235,13 @@ export function useCodeMirrorEditor(props: Props)
234235
result.push(showFunctionHelpHover)
235236
}
236237

238+
const shouldShowSpaceOmission = editorConfig.value?.space_dot_omission ?? false
239+
if (shouldShowSpaceOmission) {
240+
const {spaceOmissionPlugin, spaceOmissionTheme} = useCodeMirrorSpaceOmission()
241+
result.push(spaceOmissionPlugin)
242+
result.push(spaceOmissionTheme)
243+
}
244+
237245
extensions.value = result
238246

239247
// 如果组件还没准备好,等待下一个 tick 后设置为准备好
@@ -334,6 +342,11 @@ export function useCodeMirrorEditor(props: Props)
334342
await reRenderEditor()
335343
})
336344

345+
watch(() => editorConfig.value?.space_dot_omission, async () => {
346+
console.log('是否显示空格省略:', editorConfig.value?.space_dot_omission)
347+
await reRenderEditor()
348+
})
349+
337350
return {
338351
// 状态
339352
isReady,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import {EditorView, ViewPlugin, ViewUpdate} from '@codemirror/view'
2+
3+
export function useCodeMirrorSpaceOmission()
4+
{
5+
const spaceOmissionPlugin = ViewPlugin.fromClass(class
6+
{
7+
private styleElement: HTMLStyleElement | null = null
8+
9+
constructor(private view: EditorView)
10+
{
11+
this.updateCSS()
12+
}
13+
14+
update(update: ViewUpdate)
15+
{
16+
if (update.selectionSet) {
17+
this.updateCSS()
18+
}
19+
}
20+
21+
updateCSS()
22+
{
23+
const selection = this.view.state.selection.main
24+
25+
// 移除之前的样式
26+
if (this.styleElement) {
27+
this.styleElement.remove()
28+
this.styleElement = null
29+
}
30+
31+
if (selection.empty) {
32+
return
33+
}
34+
35+
const doc = this.view.state.doc
36+
const fromLine = doc.lineAt(selection.from)
37+
const toLine = doc.lineAt(selection.to)
38+
39+
const cssRules: string[] = []
40+
41+
// 为每个有缩进的选中行生成CSS规则
42+
for (let lineNum = fromLine.number; lineNum <= toLine.number; lineNum++) {
43+
const line = doc.line(lineNum)
44+
const text = line.text
45+
46+
// 计算空格数
47+
let spaceCount = 0
48+
for (let i = 0; i < text.length; i++) {
49+
if (text[i] === ' ') {
50+
spaceCount++
51+
}
52+
else {
53+
break
54+
}
55+
}
56+
57+
if (spaceCount > 0) {
58+
// 使用行号作为选择器,添加伪元素
59+
const arrowText = '·'.repeat(spaceCount)
60+
cssRules.push(`
61+
.cm-editor .cm-line:nth-child(${lineNum}) {
62+
position: relative;
63+
}
64+
.cm-editor .cm-line:nth-child(${lineNum})::before {
65+
content: "${arrowText}";
66+
position: absolute;
67+
left: 0.4em;
68+
top: 0;
69+
color: #9ca3af;
70+
font-weight: 500;
71+
pointer-events: none;
72+
z-index: 2;
73+
font-family: monospace;
74+
font-size: inherit;
75+
line-height: inherit;
76+
}
77+
.cm-editor .cm-selectionBackground .cm-line:nth-child(${lineNum})::before,
78+
.cm-editor .cm-line:nth-child(${lineNum}).cm-selectionBackground::before {
79+
background-color: var(--cm-selectionBackground, #b3d4fc);
80+
}
81+
`)
82+
}
83+
}
84+
85+
// 插入动态样式
86+
if (cssRules.length > 0) {
87+
this.styleElement = document.createElement('style')
88+
this.styleElement.textContent = cssRules.join('\n')
89+
document.head.appendChild(this.styleElement)
90+
}
91+
}
92+
93+
destroy()
94+
{
95+
if (this.styleElement) {
96+
this.styleElement.remove()
97+
}
98+
}
99+
})
100+
101+
const spaceOmissionTheme = EditorView.theme({
102+
'.cm-line': {
103+
position: 'relative'
104+
}
105+
})
106+
107+
return {
108+
spaceOmissionPlugin,
109+
spaceOmissionTheme
110+
}
111+
}

src/types/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ export interface EditorConfig
5353
font_size?: number
5454
show_line_numbers?: boolean
5555
show_function_help?: boolean
56+
space_dot_omission?: boolean
5657
}

0 commit comments

Comments
 (0)