⚡ perf(vscode): 代码阅读预览的文档消息里源码和着色只带一份:块不再各带一份连子块在内的整段源码和上色,编辑框按块的编辑范围从整份源码和着色里取,5126 行的消息 4.3MB → 1.9MB
This commit is contained in:
1 parent
0371712176
commit
2e3602242e
43 files changed
+501
-239
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import type { ChangeEvent, KeyboardEvent, ReactElement } from 'react'
|
||||
import type { SourceText } from './blockSource'
|
||||
import type { BlockView } from './types'
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
|
||||
import { blockSource } from './blockSource'
|
||||
import { recolor } from './segments'
|
||||
import { SegmentText } from './SegmentText'
|
||||
import { postMessage } from './vscode'
|
||||
@@ -9,6 +11,8 @@ const EDIT_DEBOUNCE_MS = 200
|
||||
|
||||
interface CodeEditorProps {
|
||||
block: BlockView
|
||||
/** 这一版文档的源码和着色:这块的源码按它的编辑范围从里面取 */
|
||||
sourceText: SourceText
|
||||
/** 文档版本:每来一份新文档都要对一次输入框内容,哪怕这一块的代码没变 */
|
||||
version: number
|
||||
autoFocus: boolean
|
||||
@@ -17,8 +21,9 @@ interface CodeEditorProps {
|
||||
}
|
||||
|
||||
/** 一块源码的编辑状态:着色层显示,透明输入框接收输入,改动防抖后整行替换回文件。 */
|
||||
export function CodeEditor({ block, version, autoFocus, onAutoFocused, onExit }: CodeEditorProps): ReactElement {
|
||||
const [text, setText] = useState(block.code)
|
||||
export function CodeEditor({ block, sourceText, version, autoFocus, onAutoFocused, onExit }: CodeEditorProps): ReactElement {
|
||||
const { code, tokens } = useMemo(() => blockSource(sourceText, block.startLine, block.endLine), [sourceText, block.startLine, block.endLine])
|
||||
const [text, setText] = useState(code)
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||
const blockRef = useRef(block)
|
||||
blockRef.current = block
|
||||
@@ -51,16 +56,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 !== code)
|
||||
return
|
||||
unconfirmed.current = null
|
||||
sentLineCount.current = null
|
||||
if (block.code === textRef.current)
|
||||
if (code === textRef.current)
|
||||
return
|
||||
if (focused)
|
||||
restoreSelection.current = [el.selectionStart, el.selectionEnd]
|
||||
setText(block.code)
|
||||
}, [version, block.code])
|
||||
setText(code)
|
||||
}, [version, code])
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const el = textareaRef.current
|
||||
@@ -121,7 +126,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(tokens, code, text)} />
|
||||
{text === '' || text.endsWith('\n') ? ' ' : ''}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user