this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Replace Compartment with StateField for message decorations

The Compartment+reconfigure approach caused "Position out of range for
changeset" RangeErrors because decorations weren't mapped through
document change transactions. A StateField maps decorations via
RangeSet.map(tr.changes) synchronously within each transaction,
keeping positions consistent with the document state.

- Add StateEffect and StateField OCaml bindings to jsoo-code-mirror
- Add Decoration.Range_set.empty and .map
- Convert editor.ml messages from Compartment to StateField+StateEffect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+58 -1
+3 -1
includes/includes.js
··· 1 1 import { EditorView, basicSetup } from "codemirror" 2 - import { EditorState, Compartment, RangeSet } from "@codemirror/state" 2 + import { EditorState, Compartment, RangeSet, StateField, StateEffect } from "@codemirror/state" 3 3 import { hoverTooltip, lineNumbers, Decoration, WidgetType } from "@codemirror/view" 4 4 import * as lint from "@codemirror/lint" 5 5 import * as autocomplete from "@codemirror/autocomplete" ··· 16 16 joo_global_object.__CM__autocomplete = autocomplete; 17 17 joo_global_object.__CM__hoverTooltip = hoverTooltip; 18 18 joo_global_object.__CM__lineNumbers = lineNumbers; 19 + joo_global_object.__CM__StateField = StateField; 20 + joo_global_object.__CM__StateEffect = StateEffect; 19 21 joo_global_object.__CM__basic_setup = basicSetup 20 22 joo_global_object.__CM__stream_parser = language; 21 23 joo_global_object.__CM__mllike = oCaml;
+2
src/code_mirror.ml
··· 3 3 module Extension = Extension 4 4 module Compartment = Compartment 5 5 module Decoration = Decoration 6 + module State_effect = State_effect 7 + module State_field = State_field
+3
src/decoration.ml
··· 47 47 48 48 let of' ranges = 49 49 Jv.call range_set "of" [| Jv.of_array Range.to_jv ranges |] |> of_jv 50 + 51 + let empty = Jv.get range_set "empty" |> of_jv 52 + let map t changes = Jv.call t "map" [| changes |] |> of_jv 50 53 end
+2
src/decoration.mli
··· 26 26 include Jv.CONV with type t := t 27 27 28 28 val of' : Range.t array -> t 29 + val empty : t 30 + val map : t -> Jv.t -> t 29 31 end
+9
src/state_effect.ml
··· 1 + type t = Jv.t 2 + 3 + include (Jv.Id : Jv.CONV with type t := t) 4 + 5 + let state_effect = Jv.get Jv.global "__CM__StateEffect" 6 + let define () = Jv.call state_effect "define" [||] 7 + let of_ t v = Jv.call t "of" [| v |] 8 + let is instance t = Jv.to_bool (Jv.call instance "is" [| t |]) 9 + let value instance = Jv.get instance "value"
+17
src/state_effect.mli
··· 1 + type t 2 + (** An effect type definition, created with {!define}. *) 3 + 4 + include Jv.CONV with type t := t 5 + 6 + val define : unit -> t 7 + (** [define ()] creates a new effect type. *) 8 + 9 + val of_ : t -> Jv.t -> Jv.t 10 + (** [of_ effect_type value] creates an effect instance carrying [value]. *) 11 + 12 + val is : Jv.t -> t -> bool 13 + (** [is instance effect_type] returns [true] if [instance] was created from 14 + [effect_type]. *) 15 + 16 + val value : Jv.t -> Jv.t 17 + (** [value instance] returns the value carried by an effect instance. *)
+11
src/state_field.ml
··· 1 + let state_field = Jv.get Jv.global "__CM__StateField" 2 + 3 + let define ~create ~update ~provide = 4 + let spec = Jv.obj [||] in 5 + Jv.set spec "create" 6 + (Jv.callback ~arity:1 (fun _state -> create ())); 7 + Jv.set spec "update" 8 + (Jv.callback ~arity:2 (fun value tr -> update value tr)); 9 + Jv.set spec "provide" 10 + (Jv.callback ~arity:1 (fun field -> Extension.to_jv (provide field))); 11 + Jv.call state_field "define" [| spec |] |> Extension.of_jv
+11
src/state_field.mli
··· 1 + val define : 2 + create:(unit -> Jv.t) -> 3 + update:(Jv.t -> Jv.t -> Jv.t) -> 4 + provide:(Jv.t -> Extension.t) -> 5 + Extension.t 6 + (** [define ~create ~update ~provide] creates a state field extension. 7 + 8 + - [create ()] returns the initial field value. 9 + - [update value transaction] computes the new value for each transaction. 10 + - [provide field] returns an extension that derives a facet from the field 11 + (e.g. [EditorView.decorations.from(field)]). *)