✨ feat(vscode): 构造参数区,改它的和来自能单独打开源码
This commit is contained in:
1 parent
e322f01edb
commit
e8ae19d084
13 files changed
+345
-70
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import type { ChangeEvent, KeyboardEvent, ReactElement } from 'react'
|
||||
import type { BlockView } from './types'
|
||||
import type { Segment } from './types'
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { recolor } from './segments'
|
||||
import { SegmentText } from './SegmentText'
|
||||
@@ -7,9 +7,17 @@ import { postMessage } from './vscode'
|
||||
|
||||
const EDIT_DEBOUNCE_MS = 200
|
||||
|
||||
/** 编辑框要的那一段源码:整块,或格子里单独打开的一段,字段一样。 */
|
||||
export interface EditableSource {
|
||||
startLine: number
|
||||
endLine: number
|
||||
code: string
|
||||
codeTokens: Segment[]
|
||||
}
|
||||
|
||||
interface CodeEditorProps {
|
||||
block: BlockView
|
||||
/** 文档版本:每来一份新文档都要对一次输入框内容,哪怕这一块的代码没变 */
|
||||
source: EditableSource
|
||||
/** 文档版本:每来一份新文档都要对一次输入框内容,哪怕这一段的代码没变 */
|
||||
version: number
|
||||
autoFocus: boolean
|
||||
onAutoFocused: () => void
|
||||
@@ -17,11 +25,11 @@ interface CodeEditorProps {
|
||||
}
|
||||
|
||||
/** 一块源码的编辑状态:着色层显示,透明输入框接收输入,改动防抖后整行替换回文件。 */
|
||||
export function CodeEditor({ block, version, autoFocus, onAutoFocused, onExit }: CodeEditorProps): ReactElement {
|
||||
const [text, setText] = useState(block.code)
|
||||
export function CodeEditor({ source, version, autoFocus, onAutoFocused, onExit }: CodeEditorProps): ReactElement {
|
||||
const [text, setText] = useState(source.code)
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||
const blockRef = useRef(block)
|
||||
blockRef.current = block
|
||||
const sourceRef = useRef(source)
|
||||
sourceRef.current = source
|
||||
const textRef = useRef(text)
|
||||
textRef.current = text
|
||||
/** 本地改过、还没在新文档里看到的文字;有它时新文档不能覆盖有焦点的输入框 */
|
||||
@@ -37,7 +45,7 @@ export function CodeEditor({ block, version, autoFocus, onAutoFocused, onExit }:
|
||||
if (!unsent.current)
|
||||
return
|
||||
unsent.current = false
|
||||
const { startLine, endLine } = blockRef.current
|
||||
const { startLine, endLine } = sourceRef.current
|
||||
const value = textRef.current
|
||||
postMessage({
|
||||
type: 'edit',
|
||||
@@ -51,16 +59,16 @@ export function CodeEditor({ block, version, autoFocus, onAutoFocused, onExit }:
|
||||
useEffect(() => {
|
||||
const el = textareaRef.current
|
||||
const focused = el !== null && document.activeElement === el
|
||||
if (focused && unconfirmed.current !== null && unconfirmed.current !== block.code)
|
||||
if (focused && unconfirmed.current !== null && unconfirmed.current !== source.code)
|
||||
return
|
||||
unconfirmed.current = null
|
||||
sentLineCount.current = null
|
||||
if (block.code === textRef.current)
|
||||
if (source.code === textRef.current)
|
||||
return
|
||||
if (focused)
|
||||
restoreSelection.current = [el.selectionStart, el.selectionEnd]
|
||||
setText(block.code)
|
||||
}, [version, block.code])
|
||||
setText(source.code)
|
||||
}, [version, source.code])
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const el = textareaRef.current
|
||||
@@ -121,7 +129,7 @@ export function CodeEditor({ block, version, autoFocus, onAutoFocused, onExit }:
|
||||
onBlur={flush}
|
||||
/>
|
||||
<pre className="cr-code" aria-hidden="true">
|
||||
<SegmentText segments={recolor(block.codeTokens, block.code, text)} />
|
||||
<SegmentText segments={recolor(source.codeTokens, source.code, text)} />
|
||||
{text === '' || text.endsWith('\n') ? ' ' : ''}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user