Skip to content

Commit 39805b6

Browse files
author
单贺喜
committed
编辑器设置值改造
1 parent 87897d1 commit 39805b6

9 files changed

Lines changed: 232 additions & 232 deletions

File tree

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
.editorContainer{
2-
// height: 100%;
3-
}
1+
.editorContainer {
2+
height: 100%;
3+
}

chat2db-client/src/components/Console/MonacoEditor/index.tsx

Lines changed: 109 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,51 @@ import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql';
66
const { keywords: SQLKeys } = language;
77
import { editorDefaultOptions, ThemeType } from '@/constants';
88
import styles from './index.less';
9-
import { monacoSqlAutocomplete } from './syntax-parser/plugin/monaco-plugin';
109

1110
export type IEditorIns = monaco.editor.IStandaloneCodeEditor;
1211
export type IEditorOptions = monaco.editor.IStandaloneEditorConstructionOptions;
1312
export type IEditorContentChangeEvent = monaco.editor.IModelContentChangedEvent;
14-
1513
interface IProps {
1614
id: string | number;
17-
value?: string;
15+
isActive?: boolean;
1816
language?: string;
19-
className: string;
20-
onChange?: (v: string, e?: IEditorContentChangeEvent) => void;
21-
didMount?: (editor: IEditorIns) => any;
17+
className?: string;
2218
options?: IEditorOptions;
2319
needDestroy?: boolean;
2420
addAction?: Array<{ id: string; label: string; action: (selectedText: string) => void }>;
21+
// onChange?: (v: string, e?: IEditorContentChangeEvent) => void;
22+
didMount?: (editor: IEditorIns) => any;
23+
onSave?: (value: string) => void; // 快捷键保存的回调
24+
onExecute?: (value: string) => void; // 快捷键执行的回调
2525
}
2626

2727
export interface IExportRefFunction {
2828
getCurrentSelectContent: () => string;
2929
getAllContent: () => string;
30+
setValue: (text: any, range?: IRangeType) => void;
3031
}
3132

3233
function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
33-
const { id, className, value = '', language = 'sql', didMount, options } = props;
34-
34+
const {
35+
id,
36+
className,
37+
language = 'sql',
38+
didMount,
39+
options,
40+
isActive,
41+
onSave,
42+
onExecute
43+
} = props;
3544
const editorRef = useRef<IEditorIns>();
36-
const [editorVal, setEditorVal] = useState('');
37-
38-
// 受控暂存value
39-
const valRef = useRef<string>('');
40-
4145
const [appTheme] = useTheme();
4246

43-
useImperativeHandle(ref, () => ({
44-
getCurrentSelectContent,
45-
getAllContent,
46-
}));
47-
48-
/**
49-
* 获取当前选中的内容
50-
* @returns
51-
*/
52-
const getCurrentSelectContent = () => {
53-
let selection = editorRef.current?.getSelection();
54-
if (!selection || selection.isEmpty()) {
55-
return '';
56-
} else {
57-
var selectedText = editorRef.current?.getModel()?.getValueInRange(selection);
58-
return selectedText || '';
59-
}
60-
};
61-
62-
/** 获取文本所有内容 */
63-
const getAllContent = () => {
64-
const model = editorRef.current?.getModel();
65-
const value = model?.getValue();
66-
return value || '';
67-
};
68-
6947
// init
7048
useEffect(() => {
7149
const editorIns = monaco.editor.create(document.getElementById(`monaco-editor-${id}`)!, {
7250
...editorDefaultOptions,
7351
...options,
74-
value,
75-
language: 'sql',
52+
value: '',
53+
language: language,
7654
theme: appTheme.backgroundColor === ThemeType.Light ? 'Default' : 'BlackTheme',
7755
});
7856
editorRef.current = editorIns;
@@ -81,7 +59,7 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
8159
monaco.editor.defineTheme('BlackTheme', {
8260
base: 'vs-dark',
8361
inherit: true,
84-
rules: [{ background: '#15161a' }],
62+
rules: [{ background: '#15161a' }] as any,
8563
colors: {
8664
// 相关颜色属性配置
8765
'editor.foreground': '#ffffff',
@@ -92,14 +70,13 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
9270
monaco.editor.defineTheme('Default', {
9371
base: 'vs',
9472
inherit: true,
95-
rules: [{ background: '#15161a' }],
73+
rules: [{ background: '#15161a' }] as any,
9674
colors: {
9775
'editor.foreground': '#000000',
9876
'editor.background': '#fff', //背景色
9977
},
10078
});
10179

102-
// monacoSqlAutocomplete(monaco, editorIns);
10380
handleRegisterTigger();
10481

10582
createAction(editorIns);
@@ -108,56 +85,64 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
10885
};
10986
}, []);
11087

111-
// value 变了,直接设置editorValue
11288
useEffect(() => {
113-
updateEditor(value);
114-
valRef.current = value;
115-
}, [value]);
89+
if (isActive && editorRef.current) {
90+
// 自定义快捷键
91+
editorRef.current.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
92+
const value = editorRef.current?.getValue();
93+
onSave?.(value || '');
94+
});
11695

117-
// editor 变了,val 没变,设置 editorValue 为 value
118-
// useEffect(() => {
119-
// if (editorVal !== valRef.current) {
120-
// updateEditor(valRef.current);
121-
// }
122-
// }, [editorVal]);
96+
editorRef.current.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, (event: Event) => {
97+
const value = getCurrentSelectContent()
98+
onExecute?.(value);
99+
});
100+
}
101+
}, [editorRef.current, isActive])
123102

103+
// 监听主题色变化切换编辑器主题色
124104
useEffect(() => {
125-
const _ref = editorRef.current?.onDidChangeModelContent((e) => {
126-
const curVal = editorRef.current?.getValue();
127-
props.onChange?.(curVal || '', e);
128-
setEditorVal(curVal || '');
129-
});
105+
monaco.editor.setTheme(appTheme.backgroundColor === ThemeType.Dark ? 'BlackTheme' : 'Default');
106+
}, [appTheme.backgroundColor]);
130107

131-
return () => _ref && _ref.dispose();
132-
}, [props.onChange]);
108+
// useEffect(() => {
109+
// const _ref = editorRef.current?.onDidChangeModelContent((e) => {
110+
// const curVal = editorRef.current?.getValue();
111+
// props.onChange?.(curVal || '', e);
112+
// });
113+
// return () => _ref && _ref.dispose();
114+
// }, [props.onChange]);
133115

134-
const updateEditor = (value: string) => {
135-
if (editorRef.current) {
136-
if (value === editorRef.current.getValue()) {
137-
return;
138-
}
139-
const model = editorRef.current.getModel();
140-
if (!model) return;
116+
useImperativeHandle(ref, () => ({
117+
getCurrentSelectContent,
118+
getAllContent,
119+
setValue
120+
}));
141121

142-
editorRef.current.pushUndoStop();
122+
const setValue = (text: any, range?: IRangeType) => {
123+
appendMonacoValue(editorRef.current, text, range)
124+
}
143125

144-
model.pushEditOperations(
145-
[],
146-
[
147-
{
148-
range: model.getFullModelRange(),
149-
text: value,
150-
},
151-
],
152-
() => [editorRef.current.getSelection()],
153-
);
154-
editorRef.current.pushUndoStop();
126+
/**
127+
* 获取当前选中的内容
128+
* @returns
129+
*/
130+
const getCurrentSelectContent = () => {
131+
let selection = editorRef.current?.getSelection();
132+
if (!selection || selection.isEmpty()) {
133+
return '';
134+
} else {
135+
var selectedText = editorRef.current?.getModel()?.getValueInRange(selection);
136+
return selectedText || '';
155137
}
156138
};
157139

158-
useEffect(() => {
159-
monaco.editor.setTheme(appTheme.backgroundColor === ThemeType.Dark ? 'BlackTheme' : 'Default');
160-
}, [appTheme.backgroundColor]);
140+
/** 获取文本所有内容 */
141+
const getAllContent = () => {
142+
const model = editorRef.current?.getModel();
143+
const value = model?.getValue();
144+
return value || '';
145+
};
161146

162147
const handleRegisterTigger = () => {
163148
// SQL关键词、 数据库、 表 、列
@@ -253,7 +238,47 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
253238
});
254239
};
255240

256-
return <div ref={ref} id={`monaco-editor-${id}`} className={cs(className, styles.editorContainer)} />;
241+
return <div ref={ref as any} id={`monaco-editor-${id}`} className={cs(className, styles.editorContainer)} />;
242+
}
243+
244+
// text 需要添加的文本
245+
// range 添加到的位置
246+
// 'end' 末尾
247+
// 'front' 开头
248+
// 'cover' 覆盖掉原有的文字
249+
// 自定义位置数组 new monaco.Range []
250+
export type IRangeType = 'end' | 'front' | 'cover' | any;
251+
252+
export const appendMonacoValue = (editor: any, text: any, range: IRangeType = 'end') => {
253+
if (!editor) {
254+
return
255+
}
256+
const model = editor?.getModel && editor.getModel(editor);
257+
// 创建编辑操作,将当前文档内容替换为新内容
258+
let newRange: IRangeType = range;
259+
text = `${text}\n`
260+
switch (range) {
261+
case 'cover':
262+
newRange = model.getFullModelRange();
263+
break;
264+
case 'front':
265+
newRange = new monaco.Range(1, 1, 1, 1);
266+
break;
267+
case 'end':
268+
const lastLine = editor.getModel().getLineCount();
269+
const lastLineLength = editor.getModel().getLineMaxColumn(lastLine);
270+
newRange = new monaco.Range(lastLine, lastLineLength, lastLine, lastLineLength);
271+
break;
272+
default:
273+
break;
274+
}
275+
const op = {
276+
range: newRange,
277+
text,
278+
};
279+
// decorations?: IModelDeltaDecoration[]: 一个数组类型的参数,用于指定插入的文本的装饰。可以用来设置文本的样式、颜色、背景色等。如果不需要设置装饰,可以忽略此参数。
280+
const decorations = [{}]; // 解决新增的文本默认背景色为灰色
281+
editor.executeEdits('setValue', [op], decorations);
257282
}
258283

259284
export default forwardRef(MonacoEditor);

0 commit comments

Comments
 (0)