···1+# This is a basic workflow to help you get started with Actions
2+3+name: CI
4+5+# Controls when the action will run. Triggers the workflow on push or pull request
6+# events but only for the master branch
7+on:
8+ push:
9+ branches:
10+ - "*"
11+ pull_request:
12+ branches:
13+ - "*"
14+15+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
16+jobs:
17+ # This workflow contains a single job called "build"
18+ build:
19+ strategy:
20+ fail-fast: false
21+ matrix:
22+ os:
23+ - ubuntu-latest
24+ ocaml-compiler:
25+ - 4.14.x
26+ # The type of runner that the job will run on
27+ runs-on: ${{ matrix.os }}
28+29+ # Steps represent a sequence of tasks that will be executed as part of the job
30+ steps:
31+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
32+ - uses: actions/checkout@v3
33+34+ - name: Set up OCaml ${{ matrix.ocaml-compiler }}
35+ uses: ocaml/setup-ocaml@v2
36+ with:
37+ # Version of the OCaml compiler to initialise
38+ ocaml-compiler: ${{ matrix.ocaml-compiler }}
39+40+ - name: Install dependencies
41+ run: |
42+ opam install . --deps-only --with-test
43+44+ - name: Build and test in release mode
45+ run: opam install . --with-test
···1+(rule
2+ (deps
3+ (source_tree %{project_root}/node_modules))
4+ (target bundle-es6.js)
5+ (enabled_if
6+ (= %{profile} "with-bundle"))
7+ (action
8+ (run
9+ %{project_root}/node_modules/esbuild/bin/esbuild
10+ %{dep:includes.js}
11+ --bundle
12+ --outfile=%{target})))
13+14+; warning: node modules are not managed by dune
15+; to generate a new bundle one should run `npm install` before the first build
16+17+(rule
18+ (deps
19+ %{project_root}/package.json
20+ %{project_root}/babel.config.js
21+ (source_tree %{project_root}/node_modules))
22+ (target bundle.js)
23+ (mode promote)
24+ (enabled_if
25+ (= %{profile} "with-bundle"))
26+ (action
27+ (run
28+ %{project_root}/node_modules/@babel/cli/bin/babel.js
29+ %{dep:bundle-es6.js}
30+ --config-file
31+ %{project_root}/babel.config.js
32+ -o
33+ %{target})))
34+35+; The bundle is only re-generated if the profile is `with-bundle`
36+; If you add new javascript dependency or update the package.json
37+; you should run `dune build --profile=with-bundle`
+17
includes/includes.js
···00000000000000000
···1+import { EditorView, EditorState, basicSetup } from "@codemirror/basic-setup"
2+import * as tooltip from "@codemirror/tooltip"
3+import * as lint from "@codemirror/lint"
4+import * as autocomplete from "@codemirror/autocomplete"
5+import * as dark from "@codemirror/theme-one-dark"
6+import * as streamParser from "@codemirror/stream-parser"
7+import { oCaml } from "@codemirror/legacy-modes/mode/mllike"
8+9+joo_global_object.__CM__view = EditorView;
10+joo_global_object.__CM__state = EditorState;
11+joo_global_object.__CM__lint = lint;
12+joo_global_object.__CM__autocomplete = autocomplete;
13+joo_global_object.__CM__tooltip = tooltip;
14+joo_global_object.__CM__basic_setup = basicSetup
15+joo_global_object.__CM__dark = dark;
16+joo_global_object.__CM__stream_parser = streamParser;
17+joo_global_object.__CM__mllike = oCaml;
···1open Code_mirror
2-3module RegExp = RegExp
04let autocomplete = Jv.get Jv.global "__CM__autocomplete"
56module Completion = struct
···89 include (Jv.Id : Jv.CONV with type t := t)
1011- let set_if_some_string t s v =
12- Jv.Jstr.set_if_some t s (Option.map Jstr.v v)
13-14- let set_string t s v =
15- Jv.Jstr.set t s (Jstr.v v)
1617 let create ~label ?detail ?info ?apply ?type_ ?boost () =
18 let o = Jv.obj [||] in
···21 set_if_some_string o "info" info;
22 Jv.set_if_some o "apply" apply;
23 set_if_some_string o "type" type_;
24- Jv.Int.set_if_some o "boost" boost;
25 o
26-27end
2829module Context = struct
···3233 include (Jv.Id : Jv.CONV with type t := t)
34000035 let token_before t types =
36 let jv = Jv.call t "tokenBefore" [| Jv.of_list Jv.of_string types |] in
37 if Jv.is_none jv then None else Some jv
···39 let match_before t regex =
40 let jv = Jv.call t "matchBefore" [| RegExp.to_jv regex |] in
41 if Jv.is_none jv then None else Some jv
0042end
4344module Result = struct
···57 o
58end
5960-type source = Context.t -> Result.t option Fut.t
61-(** A completion source *)
6263-let source_to_jv (src : source) =
64- let f ctx =
65- let fut = Fut.map (fun v -> Ok v) @@ src (Context.of_jv ctx) in
66- Fut.to_promise ~ok:(fun t -> Option.value ~default:Jv.null (Option.map Result.to_jv t)) fut
67- in
00068 Jv.repr f
00006970type config = Jv.t
7172-let config
73- ?activate_on_typing
74- ?override
75- ?max_rendered_options
76- ?default_key_map
77- ?above_cursor
78- ?option_class
79- ?icons
80- ?add_to_options
81- () =
82 let o = Jv.obj [||] in
83- Jv.Bool.set_if_some o "activateOnTyping" activate_on_typing;
84- Jv.set_if_some o "override" (Option.map (fun v -> Jv.of_list source_to_jv v) override);
85- Jv.Int.set_if_some o "maxRenderedOptions" max_rendered_options;
86- Jv.Bool.set_if_some o "defaultKeyMap" default_key_map;
87- Jv.Bool.set_if_some o "aboveCursor" above_cursor;
88- Jv.set_if_some o "optionClass" option_class;
89- Jv.Bool.set_if_some o "icons" icons;
90- Jv.set_if_some o "addToOptions" add_to_options;
91- o
9293let create ?(config = Jv.null) () =
94- Extension.of_jv @@
95- Jv.call autocomplete "autocompletion" [| config |]
9697(* type status = Active | Pending
9899-let status state =
100101-val status : Editor.State.t -> status option
102-(** Gets the current completion status *)
103104-val current_completions : Editor.State.t -> Completion.t list
105-(** Returns the current available completions *)
106-107-val selected_completion : Editor.State.t -> Completion.t option
108-* Returh the currently selected completion if any *)
10900
···1open Code_mirror
02module RegExp = RegExp
3+4let autocomplete = Jv.get Jv.global "__CM__autocomplete"
56module Completion = struct
···89 include (Jv.Id : Jv.CONV with type t := t)
1011+ let set_if_some_string t s v = Jv.Jstr.set_if_some t s (Option.map Jstr.v v)
12+ let set_string t s v = Jv.Jstr.set t s (Jstr.v v)
0001314 let create ~label ?detail ?info ?apply ?type_ ?boost () =
15 let o = Jv.obj [||] in
···18 set_if_some_string o "info" info;
19 Jv.set_if_some o "apply" apply;
20 set_if_some_string o "type" type_;
21+ Jv.Int.set_if_some o "boost" boost;
22 o
023end
2425module Context = struct
···2829 include (Jv.Id : Jv.CONV with type t := t)
3031+ let state t = Jv.get t "state" |> Editor.State.of_jv
32+ let pos t = Jv.Int.get t "pos"
33+ let explicit t = Jv.Bool.get t "explicit"
34+35 let token_before t types =
36 let jv = Jv.call t "tokenBefore" [| Jv.of_list Jv.of_string types |] in
37 if Jv.is_none jv then None else Some jv
···39 let match_before t regex =
40 let jv = Jv.call t "matchBefore" [| RegExp.to_jv regex |] in
41 if Jv.is_none jv then None else Some jv
42+43+ let aborted t = Jv.Bool.get t "aborted"
44end
4546module Result = struct
···59 o
60end
6162+module Source = struct
63+ type t = Jv.t
6465+ include (Jv.Id : Jv.CONV with type t := t)
66+67+ let create (src : Context.t -> Result.t option Fut.t) =
68+ let f ctx =
69+ let fut = Fut.map (fun v -> Ok v) @@ src (Context.of_jv ctx) in
70+ Fut.to_promise fut ~ok:(fun t ->
71+ Option.value ~default:Jv.null (Option.map Result.to_jv t))
72+ in
73 Jv.repr f
74+75+ let from_list (l : Completion.t list) =
76+ Jv.call autocomplete "completeFromList" [| Jv.of_jv_list l |] |> of_jv
77+end
7879type config = Jv.t
8081+let config ?activate_on_typing ?override ?max_rendered_options ?default_key_map
82+ ?above_cursor ?option_class ?icons ?add_to_options () =
0000000083 let o = Jv.obj [||] in
84+ Jv.Bool.set_if_some o "activateOnTyping" activate_on_typing;
85+ Jv.set_if_some o "override" (Option.map (fun v -> Jv.of_jv_list v) override);
86+ Jv.Int.set_if_some o "maxRenderedOptions" max_rendered_options;
87+ Jv.Bool.set_if_some o "defaultKeyMap" default_key_map;
88+ Jv.Bool.set_if_some o "aboveCursor" above_cursor;
89+ Jv.set_if_some o "optionClass" option_class;
90+ Jv.Bool.set_if_some o "icons" icons;
91+ Jv.set_if_some o "addToOptions" add_to_options;
92+ o
9394let create ?(config = Jv.null) () =
95+ Extension.of_jv @@ Jv.call autocomplete "autocompletion" [| config |]
09697(* type status = Active | Pending
9899+ let status state =
100101+ val status : Editor.State.t -> status option
102+ (** Gets the current completion status *)
103104+ val current_completions : Editor.State.t -> Completion.t list
105+ (** Returns the current available completions *)
000106107+ val selected_completion : Editor.State.t -> Completion.t option
108+ * Returh the currently selected completion if any *)
+80-14
src/autocomplete/autocomplete.mli
···00000001val autocomplete : Jv.t
2(** Global autocomplete value *)
34module RegExp = RegExp
56module Completion : sig
007 type t
089 include Jv.CONV with type t := t
1011 val create :
12 label:string ->
13 ?detail:string ->
14- ?info:string ->
15 ?apply:t ->
16 ?type_:string ->
17 ?boost:int ->
18- unit -> t
0000000000000019end
2021module Context : sig
0022 type t
23 (** Completion context *)
2425 include Jv.CONV with type t := t
2600000000000027 val token_before : t -> string list -> Jv.t option
002829 val match_before : t -> RegExp.t -> Jv.t option
0000030end
3132module Result : sig
0033 type t
34 (** Completion result *)
35···41 options:Completion.t list ->
42 ?span:RegExp.t ->
43 ?filter:bool ->
44- unit -> t
45- (** Creating a new completion result (see {{: https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult} the docs}).*)
00000000000046end
4748-type source = Context.t -> Result.t option Fut.t
49-(** A completion source *)
000500000005152type config
5354-val config :
55- ?activate_on_typing:bool ->
56- ?override:source list ->
57 ?max_rendered_options:int ->
58 ?default_key_map:bool ->
59 ?above_cursor:bool ->
···62 ?add_to_options:Jv.t ->
63 unit ->
64 config
65- (** Configuration options for your autocompleter, see {{: https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config} the online docs}.*)
6667-val create :
68- ?config:config -> unit ->
69- Code_mirror.Extension.t
70- (** Autocompleter *)
···1+open Code_mirror
2+3+(** Most of this documention originate from the code-mirror reference.
4+5+ {{:https://codemirror.net/6/docs/ref/#autocomplete} Visit the
6+ reference directly for additional information.} *)
7+8val autocomplete : Jv.t
9(** Global autocomplete value *)
1011module RegExp = RegExp
1213module Completion : sig
14+ (** Represents individual completions. *)
15+16 type t
17+ (** Completion *)
1819 include Jv.CONV with type t := t
2021 val create :
22 label:string ->
23 ?detail:string ->
24+ ?info:string ->
25 ?apply:t ->
26 ?type_:string ->
27 ?boost:int ->
28+ unit ->
29+ t
30+ (** Creates a completion.
31+32+ @param label The label to show in the completion picker.
33+ @param detail An optional short piece of information to show after the
34+ label.
35+ @param info Additional info to show when the completion is selected.
36+ @param apply (todo) How to apply the completion.
37+ @param type The type of the completion. This is used to pick an icon to
38+ show for the completion.
39+ @param boost
40+41+ {{:https://codemirror.net/6/docs/ref/#autocomplete.Completion} See the
42+ reference for additional information.} *)
43end
4445module Context : sig
46+ (** An instance of this is passed to completion source functions. *)
47+48 type t
49 (** Completion context *)
5051 include Jv.CONV with type t := t
5253+ val state : t -> Editor.State.t
54+ (** The editor state that the completion happens in. *)
55+56+ val pos : t -> int
57+ (** The position at which the completion is happening. *)
58+59+ val explicit : t -> bool
60+ (** Indicates whether completion was activated explicitly, or implicitly by
61+ typing. The usual way to respond to this is to only return completions when
62+ either there is part of a completable entity before the cursor, or explicit
63+ is true. *)
64+65 val token_before : t -> string list -> Jv.t option
66+ (** Get the extent, content, and (if there is a token) type of the token
67+ before this.pos. *)
6869 val match_before : t -> RegExp.t -> Jv.t option
70+ (** Get the match of the given expression directly before the cursor. *)
71+72+ val aborted : t -> bool
73+ (** Yields true when the query has been aborted. Can be useful in
74+ asynchronous queries to avoid doing work that will be ignored. *)
75end
7677module Result : sig
78+ (** Objects returned by completion sources. *)
79+80 type t
81 (** Completion result *)
82···88 options:Completion.t list ->
89 ?span:RegExp.t ->
90 ?filter:bool ->
91+ unit ->
92+ t
93+ (** Creating a new completion result (see {{: https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult} the docs}).
94+ @param from The start of the range that is being completed.
95+ @param to_ The end of the range that is being completed. Defaults to the
96+ main cursor position.
97+ @param options The completions returned.
98+ @param span When given, further input that causes the part of the document
99+ between [from] and [to_] to match this regular expression will not query
100+ the completion source again
101+ @param filter By default, the library filters and scores completions. Set
102+ filter to false to disable this, and cause your completions to all be
103+ included, in the order they were given.
104+ *)
105end
106107+module Source : sig
108+ type t
109+ (** Completion source *)
110+111+ include Jv.CONV with type t := t
112113+ val create : (Context.t -> Result.t option Fut.t) -> t
114+115+ val from_list : Completion.t list -> t
116+ (** Given a a fixed array of options, return an autocompleter that completes
117+ them. *)
118+end
119120type config
121122+val config :
123+ ?activate_on_typing:bool ->
124+ ?override:Source.t list ->
125 ?max_rendered_options:int ->
126 ?default_key_map:bool ->
127 ?above_cursor:bool ->
···130 ?add_to_options:Jv.t ->
131 unit ->
132 config
133+(** Configuration options for your autocompleter, see {{: https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config} the online docs}.*)
134135+val create : ?config:config -> unit -> Code_mirror.Extension.t
136+(** Autocompleter *)
00
+21-38
src/autocomplete/regExp.ml
···67let regexp = Jv.get (Window.to_jv G.window) "RegExp"
89-type opts =
10- | Indices
11- | Global
12- | Ignore
13- | Multiline
14- | DotAll
15- | Unicode
16- | Sticky
1718let opts_to_string = function
19- | Indices ->
20- "d"
21- | Global ->
22- "g"
23- | Ignore ->
24- "i"
25- | Multiline ->
26- "m"
27- | DotAll ->
28- "s"
29- | Unicode ->
30- "u"
31- | Sticky ->
32- "y"
3334let create ?(opts = []) s =
35 let opts =
36 match List.length opts with
37- | 0 ->
38- Jv.undefined
39 | _ ->
40- let options = List.sort_uniq Stdlib.compare opts in
41- let opt_string =
42- List.fold_left (fun acc t -> acc ^ opts_to_string t) "" options
43- in
44- Jv.of_string opt_string
45 in
46 Jv.new' regexp [| Jv.of_string s; opts |]
47···56let get_indices res =
57 let jv = Jv.get res "indices" in
58 match Jv.is_null jv with
59- | true ->
60- []
61 | false ->
62- let conv arr =
63- let indices = Jv.to_array Jv.to_int arr in
64- indices.(0), indices.(1)
65- in
66- Jv.to_list conv jv
6768let get_substring_matches res =
69 let arr = Jv.to_jv_array res in
···71 Array.sub arr 1 length |> Array.to_list |> List.map Jv.to_string
7273let exec' t s = Jv.to_option Jv.Id.to_jv @@ Jv.call t "exec" [| Jv.of_jstr s |]
74-75-let exec t s = exec' t @@ Jstr.v s
···67let regexp = Jv.get (Window.to_jv G.window) "RegExp"
89+type opts = Indices | Global | Ignore | Multiline | DotAll | Unicode | Sticky
00000001011let opts_to_string = function
12+ | Indices -> "d"
13+ | Global -> "g"
14+ | Ignore -> "i"
15+ | Multiline -> "m"
16+ | DotAll -> "s"
17+ | Unicode -> "u"
18+ | Sticky -> "y"
00000001920let create ?(opts = []) s =
21 let opts =
22 match List.length opts with
23+ | 0 -> Jv.undefined
024 | _ ->
25+ let options = List.sort_uniq Stdlib.compare opts in
26+ let opt_string =
27+ List.fold_left (fun acc t -> acc ^ opts_to_string t) "" options
28+ in
29+ Jv.of_string opt_string
30 in
31 Jv.new' regexp [| Jv.of_string s; opts |]
32···41let get_indices res =
42 let jv = Jv.get res "indices" in
43 match Jv.is_null jv with
44+ | true -> []
045 | false ->
46+ let conv arr =
47+ let indices = Jv.to_array Jv.to_int arr in
48+ (indices.(0), indices.(1))
49+ in
50+ Jv.to_list conv jv
5152let get_substring_matches res =
53 let arr = Jv.to_jv_array res in
···55 Array.sub arr 1 length |> Array.to_list |> List.map Jv.to_string
5657let exec' t s = Jv.to_option Jv.Id.to_jv @@ Jv.call t "exec" [| Jv.of_jstr s |]
58+let exec t s = exec' t @@ Jstr.v s
0
+4-11
src/autocomplete/regExp.mli
···1-(** A regular expression *)
2type t
034include Jv.CONV with type t := t
56-type opts =
7- | Indices
8- | Global
9- | Ignore
10- | Multiline
11- | DotAll
12- | Unicode
13- | Sticky
1415val create : ?opts:opts list -> string -> t
16(** Create a regular expression from a string. Internally this uses
···18 {{:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp}
19 has it's own documentation}. Note we pass noo flags at the moment. *)
2021-(** The result of executing a regular expression search on a string *)
22type result
02324val get_full_string_match : result -> string
25(** The matched text *)
···38 in a specified string [s]. *)
3940val exec' : t -> Jstr.t -> result option
41-(** Same as {!exec} only you can pass a {!Jstr.t} instead. *)
···01type t
2+(** A regular expression *)
34include Jv.CONV with type t := t
56+type opts = Indices | Global | Ignore | Multiline | DotAll | Unicode | Sticky
000000078val create : ?opts:opts list -> string -> t
9(** Create a regular expression from a string. Internally this uses
···11 {{:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp}
12 has it's own documentation}. Note we pass noo flags at the moment. *)
13014type result
15+(** The result of executing a regular expression search on a string *)
1617val get_full_string_match : result -> string
18(** The matched text *)
···31 in a specified string [s]. *)
3233val exec' : t -> Jstr.t -> result option
34+(** Same as {!exec} only you can pass a {!Jstr.t} instead. *)
···1314 module type Facet = sig
15 type t
016 include Jv.CONV with type t := t
17- type input
018 type output
1920 val of_ : t -> input -> Extension.t
21 end
2223- module FacetMaker (I : sig type t val to_jv : t -> Jv.t end) : (Facet with type input = I.t and type output = Jv.t) = struct
000024 type t = Jv.t
2526 include (Jv.Id : Jv.CONV with type t := t)
···28 type input = I.t
29 type output = Jv.t
3031- let of_ t i =
32- Jv.call t "of" [| I.to_jv i |] |> Extension.of_jv
33 end
3435- type ('i, 'o) facet = Facet : (module Facet with type input = 'i and type output = 'o and type t = 'a) * 'a -> ('i, 'o) facet
00003637 type t = Jv.t
38···46end
4748(* Helper for function *)
49-module Func (I : sig type t include Jv.CONV with type t := t end) = struct
0000050 type t = I.t -> unit
051 let to_jv f = Jv.repr f
52end
53···67 o
6869 let g = Jv.get Jv.global "__CM__view"
70-71- let create ?(opts = Jv.undefined) () =
72- Jv.new' g [| opts |]
73-74 let state t = Jv.get t "state" |> State.of_jv
75-76 let set_state t v = Jv.call t "setState" [| State.to_jv v |] |> ignore
077 module Update = struct
78 type t = Jv.t
79···85 let dom t = Jv.get t "dom" |> Brr.El.of_jv
8687 let update_listener _ : (Update.t -> unit, Jv.t) State.facet =
88- let module F = State.FacetMaker (Func(Update)) in
89- let jv = Jv.get g "updateListener" in
90- Facet ((module F), F.of_jv jv)
9192 let line_wrapping () = Jv.get g "lineWrapping" |> Extension.of_jv
93end
···1314 module type Facet = sig
15 type t
16+17 include Jv.CONV with type t := t
18+19+ type input
20 type output
2122 val of_ : t -> input -> Extension.t
23 end
2425+ module FacetMaker (I : sig
26+ type t
27+28+ val to_jv : t -> Jv.t
29+ end) : Facet with type input = I.t and type output = Jv.t = struct
30 type t = Jv.t
3132 include (Jv.Id : Jv.CONV with type t := t)
···34 type input = I.t
35 type output = Jv.t
3637+ let of_ t i = Jv.call t "of" [| I.to_jv i |] |> Extension.of_jv
038 end
3940+ type ('i, 'o) facet =
41+ | Facet :
42+ (module Facet with type input = 'i and type output = 'o and type t = 'a)
43+ * 'a
44+ -> ('i, 'o) facet
4546 type t = Jv.t
47···55end
5657(* Helper for function *)
58+module Func (I : sig
59+ type t
60+61+ include Jv.CONV with type t := t
62+end) =
63+struct
64 type t = I.t -> unit
65+66 let to_jv f = Jv.repr f
67end
68···82 o
8384 let g = Jv.get Jv.global "__CM__view"
85+ let create ?(opts = Jv.undefined) () = Jv.new' g [| opts |]
00086 let state t = Jv.get t "state" |> State.of_jv
087 let set_state t v = Jv.call t "setState" [| State.to_jv v |] |> ignore
88+89 module Update = struct
90 type t = Jv.t
91···97 let dom t = Jv.get t "dom" |> Brr.El.of_jv
9899 let update_listener _ : (Update.t -> unit, Jv.t) State.facet =
100+ let module F = State.FacetMaker (Func (Update)) in
101+ let jv = Jv.get g "updateListener" in
102+ Facet ((module F), F.of_jv jv)
103104 let line_wrapping () = Jv.get g "lineWrapping" |> Extension.of_jv
105end
+15-6
src/editor.mli
···1718 module type Facet = sig
19 type t
020 include Jv.CONV with type t := t
21- type input
022 type output
2324 val of_ : t -> input -> Extension.t
25 end
2627- module FacetMaker : functor (I : sig type t include Jv.CONV with type t := t end) -> Facet with type input = I.t
0000002829- type ('i, 'o) facet = Facet : (module Facet with type input = 'i and type output = 'o and type t = 'a) * 'a -> ('i, 'o) facet
00003031 val create : ?config:Config.t -> unit -> t
32-33 val doc : t -> Text.t
34end
35···68 end
6970 val dom : t -> Brr.El.t
71-72 val update_listener : unit -> (Update.t -> unit, Jv.t) State.facet
73-74 val line_wrapping : unit -> Extension.t
75end
···1718 module type Facet = sig
19 type t
20+21 include Jv.CONV with type t := t
22+23+ type input
24 type output
2526 val of_ : t -> input -> Extension.t
27 end
2829+ module FacetMaker : functor
30+ (I : sig
31+ type t
32+33+ include Jv.CONV with type t := t
34+ end)
35+ -> Facet with type input = I.t
3637+ type ('i, 'o) facet =
38+ | Facet :
39+ (module Facet with type input = 'i and type output = 'o and type t = 'a)
40+ * 'a
41+ -> ('i, 'o) facet
4243 val create : ?config:Config.t -> unit -> t
044 val doc : t -> Text.t
45end
46···79 end
8081 val dom : t -> Brr.El.t
082 val update_listener : unit -> (Update.t -> unit, Jv.t) State.facet
083 val line_wrapping : unit -> Extension.t
84end
-3
src/lint/lint.ml
···24 type t = Jv.t
2526 let from t = Jv.Int.get t "from"
27-28 let to_ t = Jv.Int.get t "to"
2930 type severity = Info | Warning | Error
···54 o
5556 let source t = Jv.Jstr.find t "source"
57-58 let message t = Jv.Jstr.get t "message"
59-60 let actions t = Option.map (Jv.to_array Action.to_jv) (Jv.find t "actions")
6162 include (Jv.Id : Jv.CONV with type t := t)
···24 type t = Jv.t
2526 let from t = Jv.Int.get t "from"
027 let to_ t = Jv.Int.get t "to"
2829 type severity = Info | Warning | Error
···53 o
5455 let source t = Jv.Jstr.find t "source"
056 let message t = Jv.Jstr.get t "message"
057 let actions t = Option.map (Jv.to_array Action.to_jv) (Jv.find t "actions")
5859 include (Jv.Id : Jv.CONV with type t := t)
-7
src/lint/lint.mli
···1415module Diagnostic : sig
16 type t
17-18 type severity = Info | Warning | Error
1920 val severity_of_string : string -> severity
21-22 val severity_to_string : severity -> string
2324 val create :
···32 t
3334 val severity : t -> severity
35-36 val from : t -> int
37-38 val to_ : t -> int
39-40 val source : t -> Jstr.t option
41-42 val actions : t -> Action.t array option
43-44 val message : t -> Jstr.t
45end
46
···1415module Diagnostic : sig
16 type t
017 type severity = Info | Warning | Error
1819 val severity_of_string : string -> severity
020 val severity_to_string : severity -> string
2122 val create :
···30 t
3132 val severity : t -> severity
033 val from : t -> int
034 val to_ : t -> int
035 val source : t -> Jstr.t option
036 val actions : t -> Action.t array option
037 val message : t -> Jstr.t
38end
39
+2-1
src/stream/stream.ml
···4 type t
56 include (Jv.Id : Jv.CONV with type t := t)
07 let g = Jv.get g "StreamLanguage"
89- let define (l : t) =
10 Jv.call g "define" [| to_jv l |] |> Code_mirror.Extension.of_jv
11end
···4 type t
56 include (Jv.Id : Jv.CONV with type t := t)
7+8 let g = Jv.get g "StreamLanguage"
910+ let define (l : t) =
11 Jv.call g "define" [| to_jv l |] |> Code_mirror.Extension.of_jv
12end
-6
src/text.ml
···6 type t = Jv.t
78 let from t = Jv.Int.get t "from"
9-10 let to_ t = Jv.Int.get t "to"
11-12 let number t = Jv.Int.get t "number"
13-14 let text t = Jv.Jstr.get t "text"
15-16 let length t = Jv.Int.get t "length"
17end
1819let length t = Jv.Int.get t "length"
20-21let line n t = Jv.call t "line" [| Jv.of_int n |]
22-23let to_jstr_array t = Jv.call t "toJSON" [||] |> Jv.to_jstr_array
···6 type t = Jv.t
78 let from t = Jv.Int.get t "from"
09 let to_ t = Jv.Int.get t "to"
010 let number t = Jv.Int.get t "number"
011 let text t = Jv.Jstr.get t "text"
012 let length t = Jv.Int.get t "length"
13end
1415let length t = Jv.Int.get t "length"
016let line n t = Jv.call t "line" [| Jv.of_int n |]
017let to_jstr_array t = Jv.call t "toJSON" [||] |> Jv.to_jstr_array
-1
src/text.mli
···26(** Length of the text *)
2728val line : int -> t -> Line.t
29-30val to_jstr_array : t -> Jstr.t array
···26(** Length of the text *)
2728val line : int -> t -> Line.t
029val to_jstr_array : t -> Jstr.t array
···1+open Code_mirror
2+3+let tooltip = Jv.get Jv.global "__CM__tooltip"
4+5+module Tooltip_view = struct
6+ type t = Jv.t
7+8+ include (Jv.Id : Jv.CONV with type t := t)
9+10+ let dom t = Jv.get t "dom" |> Brr.El.of_jv
11+12+ type offset = { x : int; y : int }
13+ type coords = { left : int; right : int; top : int; bottom : int }
14+15+ let offset_of_jv o = { x = Jv.Int.get o "x"; y = Jv.Int.get o "y" }
16+17+ let offset_to_jv { x; y } =
18+ let o = Jv.obj [||] in
19+ Jv.Int.set o "x" x;
20+ Jv.Int.set o "y" y;
21+ o
22+23+ let _coords_of_jv o =
24+ {
25+ left = Jv.Int.get o "left";
26+ right = Jv.Int.get o "right";
27+ top = Jv.Int.get o "top";
28+ bottom = Jv.Int.get o "bottom";
29+ }
30+31+ let coords_to_jv { left; right; top; bottom } =
32+ let o = Jv.obj [||] in
33+ Jv.Int.set o "left" left;
34+ Jv.Int.set o "right" right;
35+ Jv.Int.set o "top" top;
36+ Jv.Int.set o "bottom" bottom;
37+ o
38+39+ let offset t = Jv.get t "offset" |> offset_of_jv
40+41+ let create ~dom ?offset ?get_coords ?overlap ?mount ?update ?positioned () =
42+ let get_coords =
43+ Option.map
44+ (fun get_coords ->
45+ Jv.repr (fun pos -> get_coords (Jv.to_int pos) |> coords_to_jv))
46+ get_coords
47+ in
48+ let o = Jv.obj [||] in
49+ Jv.set o "dom" (Brr.El.to_jv dom);
50+ Jv.set_if_some o "offset" @@ Option.map offset_to_jv offset;
51+ Jv.set_if_some o "getCoords" get_coords;
52+ Jv.Bool.set_if_some o "overlap" overlap;
53+ Jv.set_if_some o "mount"
54+ @@ Option.map
55+ (fun mount -> Jv.repr (fun view -> mount (Editor.View.of_jv view)))
56+ mount;
57+ Jv.set_if_some o "update"
58+ @@ Option.map
59+ (fun update ->
60+ Jv.repr (fun view_up -> update (Editor.View.Update.of_jv view_up)))
61+ update;
62+ Jv.set_if_some o "positioned" @@ Option.map Jv.repr positioned;
63+ o
64+end
65+66+module Tooltip = struct
67+ type t = Jv.t
68+69+ include (Jv.Id : Jv.CONV with type t := t)
70+71+ let pos t = Jv.Int.get t "pos"
72+ let end_ t = Jv.to_option Jv.to_int @@ Jv.get t "end"
73+74+ let create ~pos ?end_ ~create ?above ?strict_side ?arrow () =
75+ let o = Jv.obj [||] in
76+ Jv.Int.set o "pos" pos;
77+ Jv.Int.set_if_some o "end" end_;
78+ Jv.set o "create"
79+ @@ Jv.repr (fun view ->
80+ create (Editor.View.of_jv view) |> Tooltip_view.to_jv);
81+ Jv.Bool.set_if_some o "above" above;
82+ Jv.Bool.set_if_some o "strictSide" strict_side;
83+ Jv.Bool.set_if_some o "arrow" arrow;
84+ o
85+end
86+87+type hover_config = Jv.t
88+89+let hover_config ?hide_on_change ?hover_time () =
90+ let o = Jv.obj [||] in
91+ Jv.Bool.set_if_some o "hide_on_change" hide_on_change;
92+ Jv.Int.set_if_some o "hover_time" hover_time;
93+ o
94+95+let hover_tooltip ?config source =
96+ let source =
97+ Jv.repr @@ fun view pos side ->
98+ let fut =
99+ source ~view:(Editor.View.of_jv view) ~pos:(Jv.to_int pos)
100+ ~side:(Jv.to_int side)
101+ in
102+ let fut = Fut.map (fun v -> Ok v) fut in
103+ Fut.to_promise fut ~ok:(fun t ->
104+ Option.value ~default:Jv.null (Option.map Tooltip.to_jv t))
105+ in
106+ let args =
107+ if Option.is_none config then [| source |]
108+ else [| source; Option.get config |]
109+ in
110+ Jv.call tooltip "hoverTooltip" args |> Extension.of_jv
···1+open Code_mirror
2+3+val tooltip : Jv.t
4+(** Global tooltip value *)
5+6+module Tooltip_view : sig
7+ (** Describes the way a tooltip is displayed. *)
8+9+ type t
10+ (** TooltypeView *)
11+12+ include Jv.CONV with type t := t
13+14+ val dom : t -> Brr.El.t
15+ (** The DOM element to position over the editor. *)
16+17+ type offset = { x : int; y : int }
18+ type coords = { left : int; right : int; top : int; bottom : int }
19+20+ val offset : t -> offset
21+22+ val create :
23+ dom:Brr.El.t ->
24+ ?offset:offset ->
25+ ?get_coords:(int -> coords) ->
26+ ?overlap:bool ->
27+ ?mount:(Editor.View.t -> unit) ->
28+ ?update:(Editor.View.Update.t -> unit) ->
29+ ?positioned:(unit -> unit) ->
30+ unit ->
31+ t
32+ (** Creates a TooltipView:
33+34+ @param dom The DOM element to position over the editor.
35+ @param offset Adjust the position of the tooltip relative to its anchor
36+ position.
37+ @param get_coords This method can be provided to make the tooltip view
38+ itself responsible for finding its screen position.
39+ @param overlap By default, tooltips are moved when they overlap with other
40+ tooltips. Set this to true to disable that behavior for this tooltip.
41+ @param mount Called after the tooltip is added to the DOM for the first
42+ time.
43+ @param update Update the DOM element for a change in the view's state.
44+ @param positioned Called when the tooltip has been (re)positioned.
45+46+ {{:https://codemirror.net/6/docs/ref/#tooltip.TooltipView} See the
47+ reference for additional information.} *)
48+end
49+50+(** Creates a Tooltip:
51+52+ @param pos The document position at which to show the tooltip.
53+ @param end The end of the range annotated by this tooltip, if different from
54+ pos.
55+ @param create A constructor function that creates the tooltip's DOM
56+ representation.
57+ @param above Whether the tooltip should be shown above or below the target
58+ position.
59+ @param strict_side Whether the above option should be honored when there
60+ isn't enough space on that side to show the tooltip inside the viewport.
61+ @param arrow When set to true, show a triangle connecting the tooltip element
62+ to position pos.
63+64+ {{:https://codemirror.net/6/docs/ref/#tooltip.Tooltip} See the
65+ reference for additional information.} *)
66+module Tooltip : sig
67+ (** Describes a tooltip. Values of this type, when provided through the
68+ show_tooltip facet, control the individual tooltips on the editor. *)
69+70+ type t
71+ (** Tooltip *)
72+73+ include Jv.CONV with type t := t
74+75+ val pos : t -> int
76+ (** The document position at which to show the tooltip. *)
77+78+ val end_ : t -> int option
79+ (** The end of the range annotated by this tooltip, if different from pos. *)
80+81+ val create :
82+ pos:int ->
83+ ?end_:int ->
84+ create:(Editor.View.t -> Tooltip_view.t) ->
85+ ?above:bool ->
86+ ?strict_side:bool ->
87+ ?arrow:bool ->
88+ unit ->
89+ t
90+end
91+92+type hover_config
93+94+val hover_config :
95+ ?hide_on_change:bool -> ?hover_time:int -> unit -> hover_config
96+(** Options for hover tooltips:
97+98+ @param hover_on_change When enabled (this defaults to false), close the
99+ tooltip whenever the document changes.
100+@param hover_time Hover time after which the tooltip should appear, in
101+milliseconds. Defaults to 300ms. *)
102+103+val hover_tooltip :
104+ ?config:hover_config ->
105+ (view:Editor.View.t -> pos:int -> side:int -> Tooltip.t option Fut.t) ->
106+ Extension.t
107+(** Enable a hover tooltip, which shows up when the pointer hovers over ranges
108+ of text. The callback is called when the mouse hovers over the document text.
109+ It should, if there is a tooltip associated with position pos return the
110+ tooltip description (either directly or in a promise). The side argument
111+ indicates on which side of the position the pointer is—it will be -1 if the
112+ pointer is before the position, 1 if after the position.
113+114+ Note that all hover tooltips are hosted within a single tooltip container
115+ element. This allows multiple tooltips over the same range to be "merged"
116+ together without overlapping. *)