well inuit integration kinda works but is still v broken
This commit is contained in:
152
human.ml
152
human.ml
@ -823,7 +823,7 @@ module Panel = struct
|
|||||||
, ( Box2.of_pts (Box2.o s.box) (P2.v !max_x (Box2.maxy !box))
|
, ( Box2.of_pts (Box2.o s.box) (P2.v !max_x (Box2.maxy !box))
|
||||||
, !node ) )
|
, !node ) )
|
||||||
|
|
||||||
let format_symbolic_output_buffer (ppf : Format.formatter) buf =
|
let format_symbolic_output_items (ppf : Format.formatter) buf =
|
||||||
List.iter
|
List.iter
|
||||||
Format.(
|
Format.(
|
||||||
function
|
function
|
||||||
@ -832,6 +832,10 @@ module Panel = struct
|
|||||||
| Output_string s -> Format.pp_print_string ppf s
|
| Output_string s -> Format.pp_print_string ppf s
|
||||||
| Output_spaces n | Output_indent n ->
|
| Output_spaces n | Output_indent n ->
|
||||||
Format.pp_print_string ppf (String.make n ' '))
|
Format.pp_print_string ppf (String.make n ' '))
|
||||||
|
buf
|
||||||
|
|
||||||
|
let format_symbolic_output_buffer (ppf : Format.formatter) buf =
|
||||||
|
format_symbolic_output_items ppf
|
||||||
(Format.get_symbolic_output_buffer buf)
|
(Format.get_symbolic_output_buffer buf)
|
||||||
|
|
||||||
let prettyprint ?(height = !g_text_height) ?(tag = "pretty-print")
|
let prettyprint ?(height = !g_text_height) ?(tag = "pretty-print")
|
||||||
@ -1046,6 +1050,15 @@ module Panel = struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
module InuitTextedit = struct
|
module InuitTextedit = struct
|
||||||
|
(* Most of this module stolen from https://github.com/let-def/inuit and heavily modified:
|
||||||
|
|
||||||
|
Copyright (c) 2016 Frédéric Bour
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*)
|
||||||
|
|
||||||
open Format
|
open Format
|
||||||
|
|
||||||
type 'a clickable = [> `Clickable | `Clicked] as 'a
|
type 'a clickable = [> `Clickable | `Clicked] as 'a
|
||||||
@ -1383,8 +1396,7 @@ module Panel = struct
|
|||||||
let {Patch.operation; offset= _; text_len; flags= _} =
|
let {Patch.operation; offset= _; text_len; flags= _} =
|
||||||
patch in
|
patch in
|
||||||
match operation with
|
match operation with
|
||||||
| Patch.Remove n -> remote_replace b patch n 0
|
| Patch.Remove n | Patch.Replace (n, _) ->
|
||||||
| Patch.Replace (n, _) ->
|
|
||||||
remote_replace b patch n text_len
|
remote_replace b patch n text_len
|
||||||
| Patch.Insert _ -> remote_insert b patch text_len
|
| Patch.Insert _ -> remote_insert b patch text_len
|
||||||
| Patch.Propertize n -> remote_propertize b patch n )
|
| Patch.Propertize n -> remote_propertize b patch n )
|
||||||
@ -1410,6 +1422,9 @@ module Panel = struct
|
|||||||
let trope = buffer.trope in
|
let trope = buffer.trope in
|
||||||
let offset = Trope.position trope t.left in
|
let offset = Trope.position trope t.left in
|
||||||
let length = Trope.position trope t.right - offset in
|
let length = Trope.position trope t.right - offset in
|
||||||
|
F.epr " generic_clear: t.right=%d t.left=%d@."
|
||||||
|
(Trope.position trope t.left)
|
||||||
|
(Trope.position trope t.right) ;
|
||||||
let patch = Patch.make ~offset [] (Patch.Remove length) in
|
let patch = Patch.make ~offset [] (Patch.Remove length) in
|
||||||
let observed =
|
let observed =
|
||||||
notify_observers buffer `Local t ~stop_at:[] patch in
|
notify_observers buffer `Local t ~stop_at:[] patch in
|
||||||
@ -1524,13 +1539,6 @@ module Panel = struct
|
|||||||
|
|
||||||
type 'flags clickable = [> `Clickable | `Clicked] as 'flags
|
type 'flags clickable = [> `Clickable | `Clicked] as 'flags
|
||||||
|
|
||||||
let count_char str chr =
|
|
||||||
let count = ref 0 in
|
|
||||||
for i = 0 to String.length str - 1 do
|
|
||||||
if str.[i] = chr then incr count
|
|
||||||
done ;
|
|
||||||
!count
|
|
||||||
|
|
||||||
let indent_text col text =
|
let indent_text col text =
|
||||||
if col <= 0 then text
|
if col <= 0 then text
|
||||||
else
|
else
|
||||||
@ -1591,7 +1599,7 @@ module Panel = struct
|
|||||||
List.iter
|
List.iter
|
||||||
(function
|
(function
|
||||||
| Output_string s -> F.epr "printf: %s @." s | _ -> () )
|
| Output_string s -> F.epr "printf: %s @." s | _ -> () )
|
||||||
(Format.flush_symbolic_output_buffer sob) ;
|
(Format.get_symbolic_output_buffer sob) ;
|
||||||
text t ?flags (Format.flush_symbolic_output_buffer sob)
|
text t ?flags (Format.flush_symbolic_output_buffer sob)
|
||||||
|
|
||||||
let link t ?flags fmt f =
|
let link t ?flags fmt f =
|
||||||
@ -1616,6 +1624,12 @@ module Panel = struct
|
|||||||
{t with indent= max 0 (t.indent + indent)}
|
{t with indent= max 0 (t.indent + indent)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let rec list_split i ?(left = []) = function
|
||||||
|
| [] -> (left, [])
|
||||||
|
| x :: xs ->
|
||||||
|
if i <= 0 then (left, x :: xs)
|
||||||
|
else list_split (i - 1) ~left:(left @ [x]) xs
|
||||||
|
|
||||||
module Edit = struct
|
module Edit = struct
|
||||||
open Cursor
|
open Cursor
|
||||||
|
|
||||||
@ -1623,12 +1637,6 @@ module Panel = struct
|
|||||||
{ mutable cursor: 'flags cursor
|
{ mutable cursor: 'flags cursor
|
||||||
; mutable state: Format.symbolic_output_buffer }
|
; mutable state: Format.symbolic_output_buffer }
|
||||||
|
|
||||||
let rec list_split i ?(left = []) = function
|
|
||||||
| [] -> (left, [])
|
|
||||||
| x :: xs ->
|
|
||||||
if i <= 0 then (left, x :: xs)
|
|
||||||
else list_split (i - 1) ~left:(left @ [x]) xs
|
|
||||||
|
|
||||||
let make ?(state = []) ?on_change cursor =
|
let make ?(state = []) ?on_change cursor =
|
||||||
let t =
|
let t =
|
||||||
{cursor; state= Format.make_symbolic_output_buffer ()} in
|
{cursor; state= Format.make_symbolic_output_buffer ()} in
|
||||||
@ -1667,8 +1675,7 @@ module Panel = struct
|
|||||||
; mutable next: 'flags page list
|
; mutable next: 'flags page list
|
||||||
; frame: 'flags frame option }
|
; frame: 'flags frame option }
|
||||||
|
|
||||||
and 'flags page =
|
and 'flags page = Patch.symbols * ('flags frame -> unit)
|
||||||
Format.symbolic_output_buffer * ('flags frame -> unit)
|
|
||||||
|
|
||||||
and 'flags frame =
|
and 'flags frame =
|
||||||
{title: 'flags cursor; body: 'flags cursor; nav: 'flags t}
|
{title: 'flags cursor; body: 'flags cursor; nav: 'flags t}
|
||||||
@ -1680,11 +1687,10 @@ module Panel = struct
|
|||||||
let update_frame t =
|
let update_frame t =
|
||||||
match t.frame with
|
match t.frame with
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some frame ->
|
| Some ({title; body; nav= _} as frame) ->
|
||||||
let {title; body; nav= _} = frame in
|
|
||||||
clear title ;
|
clear title ;
|
||||||
text title
|
text title (fst t.page) ;
|
||||||
(Format.get_symbolic_output_buffer (fst t.page)) ;
|
F.epr "Nav.update_frame clear body@." ;
|
||||||
clear body ;
|
clear body ;
|
||||||
(snd t.page) frame
|
(snd t.page) frame
|
||||||
|
|
||||||
@ -1748,21 +1754,21 @@ module Panel = struct
|
|||||||
| `Custom of string ]
|
| `Custom of string ]
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ edit: flag Cursor.cursor
|
{ mutable edit: flag Cursor.cursor
|
||||||
; sock: flag Patch.t Socket.t
|
; mutable sock: flag Patch.t Socket.t
|
||||||
; view: flag Nav.t
|
; mutable buf: Format.symbolic_output_item list
|
||||||
; bind: Input.Bind.state }
|
; mutable view: flag Nav.t
|
||||||
|
; mutable bind: Input.Bind.state }
|
||||||
|
|
||||||
let clear t = Cursor.clear t.edit
|
let clear t = Cursor.clear t.edit
|
||||||
let insert t = Cursor.text t.edit
|
let insert t = Cursor.text t.edit
|
||||||
|
let contents t : Format.symbolic_output_item list = t.buf
|
||||||
|
|
||||||
let contents t : Format.symbolic_output_buffer =
|
let pr_sob s =
|
||||||
(t.view.page.)
|
|
||||||
|
|
||||||
let pr s =
|
|
||||||
let sob = make_symbolic_output_buffer () in
|
let sob = make_symbolic_output_buffer () in
|
||||||
let pp = formatter_of_symbolic_output_buffer sob in
|
let pp = formatter_of_symbolic_output_buffer sob in
|
||||||
F.pf pp s ; sob
|
F.pf pp s ;
|
||||||
|
flush_symbolic_output_buffer sob
|
||||||
|
|
||||||
let bindings _t =
|
let bindings _t =
|
||||||
let open Input.Bind in
|
let open Input.Bind in
|
||||||
@ -1807,33 +1813,75 @@ module Panel = struct
|
|||||||
@@ add [([Meta], Char 'v')] [Custom (fun () -> ())]
|
@@ add [([Meta], Char 'v')] [Custom (fun () -> ())]
|
||||||
@@ empty
|
@@ empty
|
||||||
|
|
||||||
let make ?(bindings = bindings) title main =
|
let make ?(bindings = bindings) ?on_change main =
|
||||||
let sob = Format.make_symbolic_output_buffer () in
|
let open Cursor in
|
||||||
let edit, sock = Cursor.make () in
|
let edit, sock = Cursor.make () in
|
||||||
let sock' = Socket.make ~receive:ignore in
|
|
||||||
Socket.connect
|
|
||||||
~a:(Socket.endpoint sock)
|
|
||||||
~b:(Socket.endpoint sock') ;
|
|
||||||
|
|
||||||
let t =
|
let t =
|
||||||
{ edit
|
{ edit
|
||||||
; sock
|
; sock
|
||||||
; buff = sob
|
; buf= []
|
||||||
; view=
|
; view=
|
||||||
( Nav.make title
|
( F.epr "Nav.make@." ;
|
||||||
|
Nav.make (pr_sob "MR. DERPSALOT")
|
||||||
@@ fun {Nav.title= _; body; nav} ->
|
@@ fun {Nav.title= _; body; nav} ->
|
||||||
let open Cursor in
|
let open Cursor in
|
||||||
printf body "Je mens.\n\n" ;
|
printf body "Je mens.@.@." ;
|
||||||
link body "- C'est vrai." (fun _ ->
|
link body "- C'est vrai." (fun _ ->
|
||||||
Nav.push nav (pr "C'est vrai !")
|
Nav.push nav (pr_sob "C'est vrai !")
|
||||||
@@ fun {Nav.body; _} -> printf body "C'est faux." ) ;
|
@@ fun {Nav.body; _} -> printf body "C'est faux." ) ;
|
||||||
printf body "\n" ;
|
printf body "@." ;
|
||||||
link body "- C'est faux." (fun _ ->
|
link body "- C'est faux." (fun _ ->
|
||||||
Nav.push nav (pr "C'est faux !")
|
Nav.push nav (pr_sob "C'est faux !")
|
||||||
@@ fun {Nav.body; _} -> printf body "C'est vrai." ) ;
|
@@ fun {Nav.body; _} -> printf body "C'est vrai." ) ;
|
||||||
printf body "\n" ;
|
printf body "@." ;
|
||||||
printf body main )
|
printf body main ;
|
||||||
|
F.epr "Nav.make callback@." )
|
||||||
; bind= Input.Bind.init Input.Bind.empty } in
|
; bind= Input.Bind.init Input.Bind.empty } in
|
||||||
|
let sock' =
|
||||||
|
Socket.make (*~receive:ignore*)
|
||||||
|
~receive:
|
||||||
|
Patch.(
|
||||||
|
fun p ->
|
||||||
|
F.epr "Patch.t {offset=%d, operation=" p.offset ;
|
||||||
|
match p.operation with
|
||||||
|
| Insert s ->
|
||||||
|
F.epr "Insert (sob len %d) \"" (List.length s) ;
|
||||||
|
format_symbolic_output_items F.stderr s ;
|
||||||
|
F.epr "\"@."
|
||||||
|
| Replace (i, s) ->
|
||||||
|
F.epr "Replace %d \"" i ;
|
||||||
|
format_symbolic_output_items F.stderr s ;
|
||||||
|
F.epr "\"@."
|
||||||
|
| Remove i -> F.epr "Remove %d@." i
|
||||||
|
| Propertize i ->
|
||||||
|
F.epr "Propertize %d@." i ;
|
||||||
|
F.epr ", text_len=%d}@." p.text_len) in
|
||||||
|
Socket.connect ~a:t.sock ~b:(Socket.endpoint sock') ;
|
||||||
|
printf (add_flag `Prompt edit) "# " ;
|
||||||
|
Cursor.printf edit main ;
|
||||||
|
t.edit <-
|
||||||
|
observe edit (fun cursor' side p ->
|
||||||
|
let offset =
|
||||||
|
p.Patch.offset
|
||||||
|
- Inuit_region.unsafe_left_offset (region cursor') in
|
||||||
|
F.epr
|
||||||
|
"observe edit: (length t.buf)=%d; offset=(p.offset=%d \
|
||||||
|
- unsafe_left_offset=%d)=%d @."
|
||||||
|
(List.length t.buf) p.Patch.offset
|
||||||
|
(Inuit_region.unsafe_left_offset (region cursor'))
|
||||||
|
offset ;
|
||||||
|
( match p.operation with
|
||||||
|
| Insert _ ->
|
||||||
|
let sl, sr = list_split offset t.buf in
|
||||||
|
t.buf <- sl @ Patch.inserted_text p @ sr
|
||||||
|
| Replace (i, _) | Remove i ->
|
||||||
|
let sl, sr = list_split offset t.buf in
|
||||||
|
let _, sr = list_split i sr in
|
||||||
|
t.buf <- sl @ Patch.inserted_text p @ sr
|
||||||
|
| Propertize i -> F.epr "Propertize %d@." i ) ;
|
||||||
|
let callback =
|
||||||
|
if side = `Remote then on_change else None in
|
||||||
|
(p.Patch.flags, callback) ) ;
|
||||||
t.bind.bindings <- bindings t ;
|
t.bind.bindings <- bindings t ;
|
||||||
t
|
t
|
||||||
|
|
||||||
@ -1860,12 +1908,8 @@ module Panel = struct
|
|||||||
Lwt.return
|
Lwt.return
|
||||||
(draw_pp height (fun pp ->
|
(draw_pp height (fun pp ->
|
||||||
Format.pp_open_hvbox pp 0 ;
|
Format.pp_open_hvbox pp 0 ;
|
||||||
F.epr "format_symbolic_output_buffer: @." ;
|
format_symbolic_output_items pp (contents t) ;
|
||||||
format_symbolic_output_buffer F.stderr
|
|
||||||
(contents t) ;
|
|
||||||
format_symbolic_output_buffer pp (contents t) ;
|
|
||||||
F.pf pp "@." ;
|
F.pf pp "@." ;
|
||||||
F.epr "@." ;
|
|
||||||
Format.pp_close_box pp () ) ) )
|
Format.pp_close_box pp () ) ) )
|
||||||
; subpanels= []
|
; subpanels= []
|
||||||
; tag= "textedit" }
|
; tag= "textedit" }
|
||||||
@ -2261,8 +2305,8 @@ let root_actor = ref (std_actor (Store.editor "../rootstore"))
|
|||||||
open Panel
|
open Panel
|
||||||
|
|
||||||
let inuit_test =
|
let inuit_test =
|
||||||
let t = InuitTextedit.make (Format.make_symbolic_output_buffer ()) in
|
let t = InuitTextedit.make " TEST @. What @. Help @." in
|
||||||
InuitTextedit.panel (t " TEST @. What @. Help @.")
|
InuitTextedit.panel t
|
||||||
|
|
||||||
let start () =
|
let start () =
|
||||||
root_actor := std_actor inuit_test ;
|
root_actor := std_actor inuit_test ;
|
||||||
|
|||||||
Reference in New Issue
Block a user