Backspace but there's a subtle/unusual issue with enter/backspace and the text insertion occuring on the wrong line after unknown sequence.

This commit is contained in:
cqc
2022-12-14 13:23:16 -06:00
parent 5c10f3860a
commit a12db025e0
2 changed files with 573275 additions and 48 deletions

573193
_build/default/boot_js.bc.js Normal file

File diff suppressed because one or more lines are too long

130
human.ml
View File

@ -1335,7 +1335,7 @@ module Nottui = struct
let pp_may_handle ppf = function
| `Unhandled -> F.pf ppf "`Unhandled"
| `Handled -> F.pf ppf "`Unhandled"
| `Handled -> F.pf ppf "`Handled"
type mouse_handler =
x:float ->
@ -2628,8 +2628,8 @@ module Nottui_widgets = struct
let sub' str p l =
if p = 0 && l = String.length str then str else String.sub str p l
let edit_field ?(focus = Focus.make ()) ?(on_change = Fun.id)
?(on_submit = ignore) state =
let edit_field ?(focus = Focus.make ()) ?(on_change = Fun.id) state
=
let on_change a = Lwd.set state (on_change a) in
let update focus_h focus (text, pos) =
let pos = min (max 0 pos) (String.length text) in
@ -2643,9 +2643,10 @@ module Nottui_widgets = struct
[ I.string ~attr text; I.string ~attr:attr_cursor " " ]
else
[
I.string ~attr (sub' text 0 pos);
I.string ~attr:attr_cursor (sub' text pos 1);
I.string ~attr (sub' text (pos + 1) (len - pos - 1));
I.string ~attr (String.sub text 0 pos);
I.string ~attr:attr_cursor (String.sub text pos 1);
I.string ~attr
(String.sub text (pos + 1) (len - pos - 1));
]
else [ I.string (if text = "" then " " else text) ]
in
@ -2667,23 +2668,23 @@ module Nottui_widgets = struct
in
on_change (text, pos + 1);
`Handled
| `Backspace, _ ->
let text =
if pos > 0 then
| `Backspace, [] ->
if pos > 0 then (
let text =
if pos < String.length text then
String.sub text 0 (pos - 1)
^ String.sub text pos (String.length text - pos)
else if String.length text > 0 then
String.sub text 0 (String.length text - 1)
else text
else text
in
let pos = max 0 (pos - 1) in
on_change (text, pos);
`Handled
| `Enter, _ ->
in
let pos = max 0 (pos - 1) in
on_change (text, pos);
`Handled)
else `Unhandled
(* | `Enter, _ ->
on_submit (text, pos);
`Handled
`Handled *)
| `Arrow `Left, [] ->
let pos = min (String.length text) pos in
if pos > 0 then (
@ -2727,7 +2728,6 @@ module Nottui_widgets = struct
ui : Ui.t Lwd.t;
}
let _line_on_change _table _row (s, i) = (s, i)
let eq_uc_c uc c = Uchar.(equal uc (of_char c))
let copy_line_cursor (x : line) (y : line) =
@ -2736,6 +2736,16 @@ module Nottui_widgets = struct
let yi = Int.max 0 (Int.min xi (String.length ys)) in
Lwd.set y.state (ys, yi)
let line_of_cursor cursor
(f : line Lwd_table.row -> line -> Ui.may_handle) :
Ui.may_handle =
match Lwd.peek cursor with
| Some row -> (
match Lwd_table.get row with
| Some line -> f row line
| None -> `Unhandled)
| None -> `Unhandled
let cursor_move cursor
(f : line Lwd_table.row -> line Lwd_table.row option) =
match Lwd.peek cursor with
@ -2754,19 +2764,14 @@ module Nottui_widgets = struct
| None -> `Unhandled)
| None -> `Unhandled
let line_append ?(table = Lwd_table.make ()) str =
let focus = Focus.make () in
let line_make ?(focus = Focus.make ()) str =
let state = Lwd.var (str, 0) in
{ focus; state; ui = edit_field ~focus state }
let line_append ?(table = Lwd_table.make ())
?(focus = Focus.make ()) str =
let row = Lwd_table.append table in
Lwd_table.set row
{
focus;
state;
ui =
edit_field ~focus
~on_change:(_line_on_change table row)
state;
}
Lwd_table.set row (line_make ~focus str)
let line_table_of_string ?(table = Lwd_table.make ())
?(focus = Focus.make ()) (s : string) : Ui.t Lwd.t =
@ -2788,26 +2793,55 @@ module Nottui_widgets = struct
|> Lwd.join
|> Lwd.map2
~f:(fun focus ->
Ui.keyboard_area ~focus (function
| `Uchar u, [ `Ctrl ] when eq_uc_c u 'n' ->
cursor_move cursor (fun c -> Lwd_table.next c)
| `Arrow `Down, _ ->
cursor_move cursor (fun c -> Lwd_table.next c)
| `Uchar u, [ `Ctrl ] when eq_uc_c u 'p' ->
cursor_move cursor (fun c -> Lwd_table.prev c)
| `Arrow `Up, _ ->
cursor_move cursor (fun c -> Lwd_table.prev c)
| `Uchar u, [ `Meta ] when eq_uc_c u '<' ->
cursor_move cursor (fun _ -> Lwd_table.first table)
| `Uchar u, [ `Meta ] when eq_uc_c u '>' ->
cursor_move cursor (fun _ -> Lwd_table.last table)
(* | `Enter, [] -> (
let row = Lwd.peek cursor in
match Lwd_table.get row with
| Some line ->
Lwd_table.after row ~set:Lwd.set cursor
| None -> `Unhandled) *)
| _ -> `Unhandled))
Ui.keyboard_area ~focus (fun k ->
Log.debug (fun m ->
m "line_table handler %a" Ui.pp_key k);
match k with
| `Uchar u, [ `Ctrl ] when eq_uc_c u 'n' ->
cursor_move cursor (fun c -> Lwd_table.next c)
| `Arrow `Down, _ ->
cursor_move cursor (fun c -> Lwd_table.next c)
| `Uchar u, [ `Ctrl ] when eq_uc_c u 'p' ->
cursor_move cursor (fun c -> Lwd_table.prev c)
| `Arrow `Up, _ ->
cursor_move cursor (fun c -> Lwd_table.prev c)
| `Uchar u, [ `Meta ] when eq_uc_c u '<' ->
cursor_move cursor (fun _ -> Lwd_table.first table)
| `Uchar u, [ `Meta ] when eq_uc_c u '>' ->
cursor_move cursor (fun _ -> Lwd_table.last table)
| `Enter, [] ->
line_of_cursor cursor (fun old_row old_line ->
let str, pos = Lwd.peek old_line.state in
let o_str = String.sub str 0 pos in
let n_str =
String.(sub str pos (length str - pos))
in
Lwd.set old_line.state (o_str, pos);
let new_line = line_make n_str in
Focus.request new_line.focus;
Lwd.set cursor
(Some (Lwd_table.after old_row ~set:new_line));
`Handled)
| `Backspace, [] ->
line_of_cursor cursor (fun row line ->
let str, pos = Lwd.peek line.state in
match Lwd_table.prev row with
| Some row_prev when pos = 0 -> (
match Lwd_table.get row_prev with
| Some line_prev ->
let str_prev, _ =
Lwd.peek line_prev.state
in
Lwd.set line_prev.state
( str_prev ^ str,
String.length str_prev );
Focus.request line_prev.focus;
Lwd_table.remove row;
Lwd.set cursor (Some row_prev);
`Handled
| None -> `Unhandled)
| _ -> `Unhandled)
| _ -> `Unhandled))
(Focus.status focus)
(** Tab view, where exactly one element of [l] is shown at a time. *)