1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
open Quill_markdown
type msg =
| Focus_inline_by_id of int
| Focus_block_by_id of int
| Set_document of block list
| Replace_block_codeblock of int
| Split_block of int * int * int
| Update_codeblock of int * string
| Code_execution_finished of int * Quill_api.code_execution_result
let log fmt =
Printf.ksprintf (fun s -> Brr.Console.(log [ Jstr.v ("[update] " ^ s) ])) fmt
let rec update_codeblock (block : block) (target_id : int) (new_code : string) :
block =
if block.id = target_id then
match block.content with
| Codeblock { output; info; _ } ->
{ block with content = Codeblock { code = new_code; output; info } }
| _ -> block
else
match block.content with
| Blocks bs ->
{
block with
content =
Blocks
(List.map (fun b -> update_codeblock b target_id new_code) bs);
}
| _ -> block
let focus_inline_by_id document inline_id =
set_focused_document_by_id (List.map clear_focus_block document) inline_id
let focus_block_by_id document block_id =
document |> List.map clear_focus_block
|> List.map (fun b ->
if b.id = block_id then { b with focused = true } else b)
let update (m : Model.t) (message : msg) : Model.t =
match message with
| Focus_inline_by_id inline_id ->
let new_document = focus_inline_by_id m.document inline_id in
{ document = new_document }
| Focus_block_by_id block_id ->
let new_document = focus_block_by_id m.document block_id in
{ document = new_document }
| Set_document docs -> { document = docs }
| Replace_block_codeblock block_id ->
let new_document =
List.map
(fun b ->
if b.id = block_id then
{
id = block_id;
content = Codeblock { code = ""; output = None; info = None };
focused = false;
}
else b)
m.document
in
{ document = new_document }
| Update_codeblock (block_id, new_code) ->
let new_document =
List.map (fun b -> update_codeblock b block_id new_code) m.document
in
{ document = new_document }
| Code_execution_finished (block_id, result) ->
log "Received code execution result for block %d" block_id;
let output_text =
match (result.error, result.status) with
| Some err, `Error ->
log "Execution error for block %d: %s" block_id err;
"Error: " ^ err
| None, `Error ->
log "Unknown execution error for block %d" block_id;
"Unknown error"
| _, `Success ->
log "Execution success for block %d" block_id;
result.output
in
let output_block = Quill_markdown.block_of_md output_text in
let new_document =
List.map
(fun b -> set_codeblock_output_in_block b block_id output_block)
m.document
in
{ document = new_document }
| Split_block (block_id, run_id, offset) ->
let new_document =
List.map
(fun b ->
if b.id = block_id then (
match Quill_markdown.find_inline_in_block b run_id with
| None ->
log "No inline content with id %d found in block %d" run_id
block_id;
[ b ]
| Some inline ->
log "Splitting inline content with id %d in block %d" run_id
block_id;
let before, after =
Quill_markdown.split_inline inline offset
in
let new_block1 =
Quill_markdown.replace_inline_in_block b run_id before
in
let new_block2 =
Quill_markdown.replace_inline_in_block b run_id after
in
[ new_block1; new_block2 ])
else [ b ])
m.document
|> List.flatten
in
{ document = new_document }