Reference
History
首先阅读一下文档https://codemirror.net/docs/ref/#h_undo_history,可以了解到history相关通过如下:
- 可以通过history()来创建history扩展,支持一下配置
- minDepth,允许的最小history事件,默认值为100
- newGroupDelay,间隔多长多历史事件进行分组,默认值为500
- historyKeymap提供默认的history操作的键绑定
- historyField脱敏化的状态字段
- undo,撤销命令
- redo,重做命令
- undoSelection,涉及取选的撤销命令
- redoSelection,设计取选的重做命令
- undoDepth,可撤销的命令计数
- redoDepth,可重做的命令计数
- isolateHistory,在历史记录中,将有此标记的transaction与其他transaction区分开来,区分办法包括before, after以及full
- invertedEffects,此凡侧(facet)可以注册一个函数,用于增加特定的效果到历史记录中,这些效果可以被撤销和重做。
Annotation
https://codemirror.net/docs/ref/#state.Annotation
-
一种给transaction添加元数据的方式,具有扩展性。用来给影响这个transaction的动作建模(比如时间戳,源头等等)。对于transaction执行过程产生的影响,则用state effect建模比较合适。
-
结构
- type
- value
- 镜头的
define<T>()
用于定义类型
StateEffect
https://codemirror.net/docs/ref/#state.StateEffect
用于表示transaction过程中产生的影响。多用于给自定state field的变动建模。
-
结构
- value
- map,通过位置映射重调effect
is<T>
,判断effect类型- 静态的
define<Value=null>
,定义一个新的effect - 静态的mapEffects,把一个effect数组过映射一个变动集
- 静态的reconfigure,用于重配置root扩展
- 静态的appendConfig,将扩展附加到顶级配置
ChangeDesc
https://codemirror.net/docs/ref/#state.ChangeDesc
是changeSet的变体,但是不储存插入的文本,因此无法被应用,但是更轻量
- 结构
- length,变动前文档的长度
- newLength,变动后文档的长度
- empty,是否有具体变动
- iterGaps(),遍历未变动的部分
- iterChangedRanges(),遍历已变动的部分
- invertedDesc,给出逆变形式
- composeDesc,
- mapDesc,
- mapPos,
- touchesRange()
ChangeSet
https://codemirror.net/docs/ref/#state.ChangeSet
System Guide
Configuration
然后再阅读一下系统介绍文档:https://codemirror.net/docs/guide/#configuration:
-
每个编辑器状态都藏有自己的配置,通常是从激活的扩展中得出的。通常的transaction处理中,这些配置保持不变。 但是可以使用compartment或者efect来重新配置。
- 每个状态配置的直接effect是它存储的fields以及facets关联到的值。
-
一个Facet是一个扩展点。不同的扩展可以为同一facet提供值。可以从state得出face的值。
- Facet是值的聚合,它可以是多个值构成的数组,或者从若干值计算得出的值
- 可以是tab size
- 可以是event handlers
- 可是对allowMultipleSelections的计算
- Facet需要明白定义,并产生一个facet值。此值可导出,在其他地方为其充值或者取值。
- Facet大多数是静态的,但也可以从state的其他分部动态得出
- Facet是值的聚合,它可以是多个值构成的数组,或者从若干值计算得出的值
Extending CodeMirror
-
State Fields可以让扩展存储额外的信息到state中,比如undo需要存储撤销记录,folding需要存储被折叠的区域。
- 扩展可以自定义State Field,但是只能存储不可改值。
- State field采用reducer与state的剩余部分保持同步,每次state更新,都会调用一个函数,参数为当前值和需处理的transaction
- annotations和effect可以帮助沟通state field的变化
-
扩展的结构
-
通常,在编辑器上实现一个有用的扩展需要涉及几方面:一个state field用于保持状态、一个基底主题来提供样式,一个视图插件来管理输入输出,再加上一些命令,然后带一个facet用于配置。
-
常见的办法是为扩展导出一个返回扩展值的函数。
-
扩展会拉入其他扩展,所以要考虑扩展被拉入多次的情况。
-
扩展的多个例现如果是同一个值,那么编辑器会自动去重
-
但是如果扩展的配置会发生变化呢?有时候这是个错误,但其他情况下可以定义一定的策略来协调不同的配置。可以用facet来担此任。此facet可以藏于模块内,其整合函数要么协调不同的配置,要么抛出错误。
-
history.ts
history相关部分的源码在https://github.com/codemirror/commands.git中,只有一个文件,即src/history.ts
。
-
定义了一个annotation:fromHistory,值为
{side: BranchName, rest: Branch}
- BranchName是redo、undo二选一,Branch是历史事件合集
-
定义了一个annotation:isolateHistory
-
定义了一个facet:invertedEffects
-
定义了一个facet:historyConfig,内部用
-
定义了一个state field:historyField,其值类型是HistoryState。
- HistoryState
- 有两个分支,done,undo
- addChanges,记录一个某时发生的HistEvent事件
- 设定层层条件之后,将一个HistEvent添加到done分支
- addSelection,记录一个某时发生的取选
- addMapping,对于给定的mapping做出反应
- pop,从某分支中弹出一个记录
- HistoryState
-
定义了一个HistEvent类型,用来保存一组改动或者效应
- 结构
- changes,类型为ChangeSet
- effects,类型为
StateEffect<any>[]
- mapped,累计的mapping
- startSelection,此事件之前的取选
- selectionAfter,此事件之后的取选
- 结构
Example: Undoable Effects
如果将某操作以state effect建模,则可以让history模块来重做和撤销之。 文中举的例子是为文本增加高亮。
感想
- facet或许可以翻译成
剖面
吗?
(下面没有了)