monaco-editor.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { ChatContext } from '@/app/chat-context';
  2. import { formatSql } from '@/utils';
  3. import Editor, { OnChange, loader } from '@monaco-editor/react';
  4. import { useLatest } from 'ahooks';
  5. import classNames from 'classnames';
  6. import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
  7. import { useContext, useMemo } from 'react';
  8. import { register } from './ob-editor/ob-plugin';
  9. import { getModelService } from './ob-editor/service';
  10. import { github, githubDark } from './ob-editor/theme';
  11. loader.config({ monaco });
  12. export interface ISession {
  13. getTableList: (schemaName?: string) => Promise<string[]>;
  14. getTableColumns: (tableName: string) => Promise<{ columnName: string; columnType: string }[]>;
  15. getSchemaList: () => Promise<string[]>;
  16. }
  17. interface MonacoEditorProps {
  18. className?: string;
  19. value: string;
  20. language: string;
  21. onChange?: OnChange;
  22. thoughts?: string;
  23. session?: ISession;
  24. }
  25. monaco.editor.defineTheme('github', github as any);
  26. monaco.editor.defineTheme('githubDark', githubDark as any);
  27. export default function MonacoEditor({
  28. className,
  29. value,
  30. language = 'mysql',
  31. onChange,
  32. thoughts,
  33. session,
  34. }: MonacoEditorProps) {
  35. // merge value and thoughts
  36. const editorValue = useMemo(() => {
  37. if (language !== 'mysql') {
  38. return value;
  39. }
  40. if (thoughts && thoughts.length > 0) {
  41. return formatSql(`-- ${thoughts} \n${value}`);
  42. }
  43. return formatSql(value);
  44. }, [value, thoughts]);
  45. const sessionRef = useLatest(session);
  46. const context = useContext(ChatContext);
  47. async function pluginRegister(editor: monaco.editor.IStandaloneCodeEditor) {
  48. const plugin = await register();
  49. plugin.setModelOptions(
  50. editor.getModel()?.id || '',
  51. getModelService(
  52. {
  53. modelId: editor.getModel()?.id || '',
  54. delimiter: ';',
  55. },
  56. () => sessionRef.current || null,
  57. ),
  58. );
  59. }
  60. return (
  61. <Editor
  62. className={classNames(className)}
  63. onMount={pluginRegister}
  64. value={editorValue}
  65. defaultLanguage={language}
  66. onChange={onChange}
  67. theme={context?.mode !== 'dark' ? 'github' : 'githubDark'}
  68. options={{
  69. minimap: {
  70. enabled: false,
  71. },
  72. wordWrap: 'on',
  73. }}
  74. />
  75. );
  76. }