⚡ perf(vscode): 代码阅读预览发给页面的块只记相对位置:块在源码里占的地方记成离前一块多远、自己多长,块里名字的下标从块的开头算,页面从文件开头累加回文件里的位置、和扩展端打交道的地方都在一处换算;靠前改了代码,后面内容没变的块发过去一模一样,扩展端自己的块和发给页面的块分成两种类型
This commit is contained in:
1 parent
3a2815c19c
commit
ad5f559e92
43 files changed
+980
-424
No files matched your search
@@ -2,36 +2,50 @@ import type { LucideIcon } from 'lucide-react'
|
||||
import type { CSSProperties, ReactElement } from 'react'
|
||||
import type { NameMap } from './displayNames'
|
||||
import type { Highlight, OccurrenceStyle } from './occurrences'
|
||||
import type { Placement } from './placement'
|
||||
import type { ReadableStore } from './store'
|
||||
import type { GroupStyle, Inline, Segment, SegmentGroup, ShownName } from './types'
|
||||
import { createContext, memo, useContext, useState } from 'react'
|
||||
import { sameShownName, shownName } from './displayNames'
|
||||
import { KIND_ICON_COMPONENTS } from './kindIcons'
|
||||
import { isCurrent, segmentOccurrence, sourceOf } from './occurrences'
|
||||
import { NO_PLACEMENT } from './placement'
|
||||
import { staticStore, useStore } from './store'
|
||||
|
||||
/** 页面上文字的两样标记:中文名(下标 → 显示成什么),眼下高亮着的名字(没有高亮时没有)。 */
|
||||
/**
|
||||
* 页面上文字的标记:中文名(文件里的下标 → 显示成什么),眼下高亮着的名字(没有高亮时没有),和各块在文件里的位置
|
||||
* (文字里的下标从所在那块的开头算,按它换成文件里的下标再去查)。
|
||||
*/
|
||||
export interface TextMarks {
|
||||
names: NameMap
|
||||
highlight?: Highlight
|
||||
placement: Placement
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字的标记从哪份 store 读:页面上是 App 的那份(中文名、单击高亮都记在里面);定义卡片浮窗是那个文件的中文名,钉住的行不画高亮。
|
||||
* 每段文字只订阅自己那几段的标记。
|
||||
*/
|
||||
export const TextMarksContext = createContext<ReadableStore<TextMarks>>(staticStore({ names: new Map() }))
|
||||
export const TextMarksContext = createContext<ReadableStore<TextMarks>>(staticStore({ names: new Map(), placement: NO_PLACEMENT }))
|
||||
|
||||
/** 文字在哪块的卡片里(块 id):卡片、钉住的卡片头按它给里面的文字;卡片外面的文字(编辑框的着色)不带下标,没有 */
|
||||
export const BlockIdContext = createContext<string | undefined>(undefined)
|
||||
|
||||
/**
|
||||
* 按词性给每一段上色,颜色在 codeReader.css 的 .cr-role-* 里按主题切换,带自己颜色(color)的段用它(.cr-colored);带源码下标的名字记在 data-offset 上
|
||||
* (讲别处名字的段记那个名字的下标,见 sourceOf),跳到定义、高亮各处出现用;是眼下高亮着的名字的一处出现时 data-occurrence 标出底色,是当前那一处(点中的、用键盘跳到的)时
|
||||
* 按词性给每一段上色,颜色在 codeReader.css 的 .cr-role-* 里按主题切换,带自己颜色(color)的段用它(.cr-colored);带下标的名字把块里的下标记在 data-offset 上
|
||||
* (讲别处名字的段记那个名字的下标,见 sourceOf;换成文件里的见 nameOffset),跳到定义、高亮各处出现用;是眼下高亮着的名字的一处出现时 data-occurrence 标出底色,是当前那一处(点中的、用键盘跳到的)时
|
||||
* 再标 data-current。起了中文名的名字显示中文名(data-name),悬停看原名,定义处本身在后面淡淡写原名;下标照旧,跳到定义、高亮照常。
|
||||
* 带悬停提示(tooltip)的段悬停看它。
|
||||
* 框起来的一组词画成小框,框里的词同样处理。
|
||||
* 中文名和高亮只订阅自己这几段的(TextMarksContext):中文名到了、换了高亮的名字,只有字或底色变了的那几串文字重画。
|
||||
* 中文名和高亮只订阅自己这几段的(TextMarksContext),按所在那块(BlockIdContext)在文件里的位置查:中文名到了、换了高亮的名字,只有字或底色变了的那几串文字重画;
|
||||
* 块只是挪了位置时查出来的还是那些,不重画。
|
||||
*/
|
||||
export const SegmentText = memo(({ segments }: { segments: Inline[] }): ReactElement => {
|
||||
const marks = useStore(useContext(TextMarksContext), current => segments.map(piece => 'role' in piece ? markOf(piece, current) : undefined), sameMarks)
|
||||
const block = useContext(BlockIdContext)
|
||||
const marks = useStore(useContext(TextMarksContext), (current) => {
|
||||
const base = block === undefined ? undefined : current.placement.of(block)?.offset
|
||||
return segments.map(piece => 'role' in piece && base !== undefined ? markOf(piece, base, current) : undefined)
|
||||
}, sameMarks)
|
||||
return (
|
||||
<>
|
||||
{segments.map((piece, index) => {
|
||||
@@ -44,7 +58,7 @@ export const SegmentText = memo(({ segments }: { segments: Inline[] }): ReactEle
|
||||
key={index}
|
||||
className={piece.color ? `cr-role-${piece.role} cr-colored` : `cr-role-${piece.role}`}
|
||||
style={piece.color && { '--color-dark': piece.color.dark, '--color-light': piece.color.light } as CSSProperties}
|
||||
data-offset={sourceOf(piece)?.start}
|
||||
data-offset={sourceOf(piece, 0)?.start}
|
||||
data-occurrence={mark?.occurrence}
|
||||
data-current={mark?.current ? '' : undefined}
|
||||
data-name={shown?.name}
|
||||
@@ -67,10 +81,11 @@ interface SegmentMark {
|
||||
current: boolean
|
||||
}
|
||||
|
||||
function markOf(piece: Segment, { names, highlight }: TextMarks): SegmentMark | undefined {
|
||||
const shown = shownName(piece, names)
|
||||
const occurrence = highlight && segmentOccurrence(piece, highlight.occurrences)
|
||||
const current = highlight !== undefined && isCurrent(piece, highlight)
|
||||
/** 一段的标记;段里的下标从所在那块的开头算,那块的开头在文件里的下标是 base。 */
|
||||
function markOf(piece: Segment, base: number, { names, highlight }: TextMarks): SegmentMark | undefined {
|
||||
const shown = shownName(piece, base, names)
|
||||
const occurrence = highlight && segmentOccurrence(piece, base, highlight.occurrences)
|
||||
const current = highlight !== undefined && isCurrent(piece, base, highlight)
|
||||
return shown || occurrence || current ? { shown, occurrence, current } : undefined
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user