{"version":3,"file":"use-base-extensions.cjs","sources":["../../../app/hooks/use-base-extensions.ts"],"sourcesContent":["import { EditorState, Extension } from \"@codemirror/state\"\nimport {\n  drawSelection,\n  dropCursor,\n  EditorView,\n  highlightActiveLine,\n  keymap,\n  lineNumbers,\n  ViewUpdate,\n  highlightActiveLineGutter,\n} from \"@codemirror/view\"\nimport { useMemo } from \"react\"\nimport { history } from \"@codemirror/commands\"\nimport { closeBrackets, closeBracketsKeymap } from \"@codemirror/autocomplete\"\nimport { highlightSelectionMatches } from \"@codemirror/search\"\nimport { bracketMatching, foldGutter, indentOnInput } from \"@codemirror/language\"\nimport type { CursorPosition } from \"../code-editor\"\n\ninterface BaseExtensionsOptions {\n  includeKeymap?: boolean,\n  includeLineNumbers?: boolean,\n  lineWrapping?: boolean,\n  onChange?: (value: string, viewUpdate: ViewUpdate) => void,\n  onCursorChange?: (position: CursorPosition) => void,\n  onEditorUpdate?: (update: ViewUpdate) => void,\n  onEndChange?: (value: string) => void,\n  onSelectionChange?: (characterCount: number) => void,\n  placeholder?: string,\n  readonly?: boolean,\n  theme?: Extension\n}\n\n/**\n * 提供代码编辑器的基础扩展集合\n * 包括：行号、历史、括号匹配、折叠、缩进等\n * \n * @param options - 配置选项\n * @returns 基础扩展数组\n */\nexport function useBaseExtensions(options: BaseExtensionsOptions = {}): Extension[] {\n  const {\n    readonly = false,\n    lineWrapping = true,\n    onChange,\n    onCursorChange,\n    onEndChange,\n    onSelectionChange,\n    onEditorUpdate,\n    theme,\n    includeLineNumbers = true,\n    includeKeymap = true,\n  } = options\n\n  const extensions = useMemo(() => {\n    const baseExtensions: Extension[] = []\n\n    // 基础视图扩展\n    if (includeLineNumbers) {\n      baseExtensions.push(lineNumbers())\n    }\n    \n    baseExtensions.push(\n      highlightActiveLineGutter(),\n      highlightActiveLine(),\n    )\n\n    // 行换行\n    if (lineWrapping) {\n      baseExtensions.push(EditorView.lineWrapping)\n    }\n\n    // 主题\n    if (theme) {\n      baseExtensions.push(theme)\n    }\n\n    // 只读模式\n    if (readonly) {\n      baseExtensions.push(\n        EditorState.readOnly.of(true),\n        EditorView.editable.of(false)\n      )\n    } else {\n      // 编辑功能扩展\n      baseExtensions.push(\n        history(),\n        foldGutter({\n          markerDOM: (open) => {\n            const svgNS = \"http://www.w3.org/2000/svg\"\n            const wrapper = document.createElement(\"div\")\n            wrapper.classList.add(\"cm-fold-marker\")\n            wrapper.style.cursor = \"default\"\n            const svgElement = document.createElementNS(svgNS, \"svg\")\n            svgElement.setAttribute(\"viewBox\", \"0 0 10 10\")\n            svgElement.setAttribute(\"width\", \"6\")\n            svgElement.setAttribute(\"height\", \"6\")\n            const pathElement = document.createElementNS(svgNS, \"path\")\n            const d = open ? \"M1 3 L5 7 L9 3\" : \"M3 1 L7 5 L3 9\"\n            pathElement.setAttribute(\"d\", d)\n            pathElement.setAttribute(\"fill\", \"none\")\n            pathElement.setAttribute(\"stroke\", \"currentColor\")\n            pathElement.setAttribute(\"stroke-width\", \"1.5\")\n            pathElement.setAttribute(\"stroke-linecap\", \"round\")\n            svgElement.appendChild(pathElement)\n            wrapper.appendChild(svgElement)\n            return wrapper\n          },\n        }),\n        indentOnInput(),\n        bracketMatching(),\n        closeBrackets(),\n        highlightSelectionMatches({ minSelectionLength: 2 }),\n        drawSelection(),\n        dropCursor(),\n        EditorState.allowMultipleSelections.of(true),\n        EditorView.clickAddsSelectionRange.of(\n          (event) => event.altKey && !event.metaKey && !event.shiftKey,\n        ),\n      )\n\n      // 键盘映射（如果需要）\n      if (includeKeymap) {\n        baseExtensions.push(\n          keymap.of(closeBracketsKeymap),\n        )\n      }\n\n      // 事件监听器\n      if (onChange || onCursorChange || onSelectionChange || onEditorUpdate) {\n        baseExtensions.push(\n          EditorView.updateListener.of((update: ViewUpdate) => {\n            // 触发编辑器更新回调\n            onEditorUpdate?.(update)\n\n            // 文档变化回调\n            if (onChange && update.docChanged) {\n              const newValue = update.state.doc.toString()\n              onChange(newValue, update)\n            }\n\n            // 光标位置变化回调\n            if (onCursorChange && update.selectionSet) {\n              const { state } = update\n              const pos = state.selection.main.head\n              const lineInfo = state.doc.lineAt(pos)\n\n              onCursorChange({\n                column: pos - lineInfo.from + 1,\n                line: lineInfo.number,\n              })\n            }\n\n            // 选中字符数变化回调\n            if (onSelectionChange && update.selectionSet) {\n              const { state } = update\n              const { from, to } = state.selection.main\n              const characterCount = to - from\n\n              onSelectionChange(characterCount)\n            }\n          })\n        )\n      }\n\n      // 结束触发：在编辑器失焦时回调最终内容\n      if (onEndChange) {\n        baseExtensions.push(\n          EditorView.domEventHandlers({\n            blur: (_event, view) => {\n              const value = view.state.doc.toString()\n              onEndChange(value)\n            },\n          })\n        )\n      }\n    }\n\n    return baseExtensions\n  }, [\n    readonly,\n    lineWrapping,\n    onChange,\n    onCursorChange,\n    onEndChange,\n    onSelectionChange,\n    onEditorUpdate,\n    theme,\n    includeLineNumbers,\n    includeKeymap,\n  ])\n\n  return extensions\n}\n\n"],"names":["useMemo","lineNumbers","highlightActiveLineGutter","highlightActiveLine","EditorView","EditorState","history","foldGutter","indentOnInput","bracketMatching","closeBrackets","highlightSelectionMatches","drawSelection","dropCursor","keymap","closeBracketsKeymap"],"mappings":"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"}